C ++ 추상 클래스 : 생성자 예 또는 아니오?
하나 이상의 가상 순수 함수가있는 클래스는 추상적이며 새 객체를 만드는 데 사용할 수 없으므로 생성자가 없습니다.
다음 예제를 제공하는 책을 읽고 있습니다.
class Employee {
public:
Employee(const char*, const char*);
~Employee();
const char* getFirstName() const;
const char* getLastName() const;
virtual double earnings() const=0 // pure virtual => abstract class
virtual void print() const
private:
char* firstName, lastName;
};
클래스가 추상적 인 경우 생성자가있는 이유는 무엇입니까? 나중에이 클래스를 사용합니다 ( Boss
에서 공개적으로 파생 됨 Employee
).
void Boss::Boss (const char* first, const char* last, double s)
: Employee (first, last)
순수 가상 기능을 가진 클래스가 추상적이고 인스턴스화 될 수 없다고 말하는 것이 맞습니다. 그러나 생성자를 가질 수 없다고 말하는 것은 틀 렸습니다.
실제로 예제에서 알 수 있듯이 추상 클래스에는이 클래스의 멤버 함수에서 사용할 수있는 전용 멤버가있을 수 있습니다. 그리고 이러한 멤버는 초기화되어야합니다. 생성자는이를 수행하는 방법입니다 (예 : 두 번째 샘플에서 볼 수 있듯이 파생 클래스의 초기화 목록 사용). 제 생각에는 init()
예를 들어 함수 보다 더 좋습니다 .
대답에서 내 의견 편집 : 추상 클래스는 멤버 변수와 잠재적으로 비가 상 멤버 함수를 가질 수 있으므로 전자의 모든 파생 클래스가 특정 기능을 구현합니다.
그런 다음 이러한 멤버 변수의 초기화에 대한 책임은 추상 클래스에 속할 수 있습니다 ( 파생 클래스가 초기화 할 수 없지만 사용 / 신뢰할 수있는 일부 상속 된 멤버 함수를 사용할 수 있기 때문에 적어도 항상 private 멤버의 경우) 이 회원들). 따라서 추상 클래스가 생성자를 구현하는 것이 완벽하게 합리적입니다.
순수 가상 함수가있는 클래스는 인스턴스화 할 수 없습니다. 이를 확장하고 누락 된 기능을 제공하는 하위 클래스가있을 것으로 예상됩니다.
이러한 하위 클래스는 인스턴스화 될 때 기본 클래스를 구성하고 수퍼 클래스의 생성자를 호출하므로 추상 클래스에 C ++에서 생성자가 있습니다.
따라서 인스턴스를 직접 생성하고 생성자를 직접 호출 할 수는 없지만 향후 하위 클래스는 그렇게 할 것입니다.
Employee
클래스는 데이터를 가지고 있으며,이 데이터는 어떻게 든 초기화 될 필요가있다. 생성자는이를 수행하는 좋은 방법입니다.
기본 추상 클래스에 생성자가없는 firstname , lastname
경우 파생 클래스의 개체를 만들 때 파생 클래스의 멤버에 값을 어떻게 할당 합니까?
데이터 를 추가 하고 구현 하는 Manager Class
파생 항목 이 있다고 가정 Employee
합니다 . 이제 추상 클래스입니다 만 이다 따라서 당신의 객체를 가질 수 있습니다 . 그러나 인스턴스화 할 때에서 상속 된 멤버에 값을 초기화 / 할당해야합니다 . 한 가지 방법은 이 목적을 위해 기본 클래스에 가질 수 있으며 생성자에서 사용할 수 있습니다. 또는 더 편리한 방법은 .Salary
earning()
Employee
Manager
concrete class
Manager
Manager
base class i.e. Employee
setFirstName() & setLastName()
derived class i.e. Manager
base abstract class Employee
아래 코드를 참조하십시오.
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
class Employee {
public:
Employee(const char*, const char*);
~Employee();
const char* getFirstName() const;
const char* getLastName() const;
virtual double earnings() const=0; // pure virtual => abstract class
virtual void print() const;
private:
char* firstname;
char* lastname;
};
Employee::Employee(const char* first, const char* last){
firstname= (char*) malloc((strlen(first)+1)*sizeof(char));
lastname= (char*) malloc((strlen(last)+1)*sizeof(char));
strcpy(firstname,first);
strcpy(lastname,last);
}
Employee::~Employee(){
free(firstname);
free(lastname);
cout << "Employee destructed" << endl;
}
const char* Employee::getFirstName() const{ return firstname;}
const char* Employee::getLastName() const{ return lastname; }
void Employee::print() const{
cout << "Name: " << getFirstName() << " " << getLastName() << endl;
}
class Manager:public Employee{
public:
Manager(char* firstname,char* lastname,double salary):
Employee(firstname,lastname),salary(salary){}
~Manager(){}
double earnings() const {return salary;}
private:
double salary;
};
int main(){
Manager Object("Andrew","Thomas",23000);
Object.print();
cout << " has Salary : " << Object.earnings() << endl;
return 0;
}
firstName 및 lastName 은 비공개 멤버이며 Boss가 액세스 할 수 없습니다. 이들에 대한 모든 인터페이스는 초기화를 포함하여 Employee 클래스에 있어야합니다.
"An abstract class contains at least one pure virtual function. You declare a pure virtual function by using a pure specifier (= 0) in the declaration of a virtual member function in the class declaration."
regarding:
void Boss::Boss (const char* first, const char* last, double s)
: Employee (first, last)
first
and last
are defined in the base class, therefore, in order to initialize them, we need to make a call to the constructor of the base class : Employee (first, last)
To initialize firstName and lastName. Otherwise you will have to write a code to initilze them in each derived classes' constructors
The purpose of Abstract class is that you want to extend some functionality by derived classes. Can it have constructor? Yes it can and the purpose is to initialize local variables from the base class. You should avoid using public constructor in Abstract and use protected only.
The example you have is not a good example. Not sure what book it is but that the bad example. Its like defining int variable with name of variable "iAmString" :).
int iAmString = 12;
Cheers
ReferenceURL : https://stackoverflow.com/questions/19808667/c-abstract-class-constructor-yes-or-no
'programing' 카테고리의 다른 글
클래스에서 다른 메서드를 호출하는 방법은 무엇입니까? (0) | 2021.01.14 |
---|---|
디버거에서 일시 중지 된 경우 Chrome 개발 도구에서 아래로 스크롤 (0) | 2021.01.14 |
React.js : 클릭시 컴포넌트를 추가하는 방법은 무엇입니까? (0) | 2021.01.14 |
C # 용 자동 코드 포맷터가 있습니까? (0) | 2021.01.14 |
Spring Batch에서 Job의 여러 단계간에 데이터를 어떻게 공유 할 수 있습니까? (0) | 2021.01.14 |