在使用继承和抽象基类时,如果你的基类有一个纯虚函数virtual void doSomething() = 0;,这意味着从这个基类继承的每个类都必须实现这个函数;另外,这个基类不能被实例化,因为它是抽象的。
在使用构造函数进行公共、受保护和私有成员访问时,将限制类对外部调用者的行为方式。如果构造函数是公共的,则可以调用该构造函数并创建该对象的实例,前提是该类不是抽象的。当构造函数受到保护时,不能从类外部调用构造函数;但是,任何从它继承的类都可以调用受保护的构造函数,除非使用了朋友修饰符。
这就是抽象的意思。抽象的基类不能是对象,而是一个封装的概念或想法,包含所有派生类之间共有的所有信息。它是可以实例化的对象的子对象。
如果您在本例中使用纯虚拟方法,则无法实例化基类,但是如果您仅使用虚拟方法而没有纯虚拟方法,则可以实例化它!但是要小心基类中的虚方法并在构造函数中调用它们,它们可能很危险。
我将展示一个包含公共和受保护构造函数的抽象基类的简单示例。第一种情况是使用公共构造函数:
class Animal {
public:
enum AnimalType {
AMPHIBIAN,
BIRD,
FISH,
MAMMAL,
REPTILE,
}; // AnimalType
protected:
AnimalType m_type;
int m_age;
float m_weight;
std::string m_strVoice;
public:
Animal( AnimalType type, int age, float weight ) :
m_type( type ), m_age( age ), m_weight( weight )
{}
virtual ~Animal() {} // Virtual Due To Inheritance
AnimalType getType() const { return m_type; }
void setAge( int age ) { m_age = age; }
int getAge() const { return m_age; }
void setWeight( float weight ) { m_weight = weight; }
float getWeight() const { return m_weight; }
virtual std::string speak() = 0; // Purely Virtual All Derived Class Must Implement This
// Abstract Class Can Not Be Instantiated
}; // Animal
class Dog : public Animal {
public:
Dog( int age, float weight ) : Animal( AnimalType::MAMMAL, age, weight ) {}
virtual ~Dog() {}
std::string speak() { return std::string( "rough" ); }
}; // Dog
使用这种结构,您只能在源代码的其他位置创建 Dog 对象。
现在用上面的例子来演示一个受保护的构造函数:
class Animal {
public:
enum AnimalType {
AMPHIBIAN,
BIRD,
FISH,
MAMMAL,
REPTILE,
}; // AnimalType
protected:
AnimalType m_type;
int m_age;
float m_weight;
std::string m_strVoice;
public:
virtual ~Animal() {} // Virtual Due To Inheritance
AnimalType getType() const { return m_type; }
void setAge( int age ) { m_age = age; }
int getAge() const { return m_age; }
void setWeight( float weight ) { m_weight = weight; }
float getWeight() const { return m_weight; }
virtual std::string speak() = 0; // Purely Virtual All Derived Class Must Implement This
// Abstract Class Can Not Instantiate
protected:
Animal( AnimalType type, int age, float weight ) :
m_type( type ), m_age( age ), m_weight( weight ) {}
// Constructor Is Protected - Doesn't Necessarily Make It Abstract
// But Prevents Outside Code From Accessing This Constructor Only
// Allowing Either Derived Classes Or Friends To Access This Constructor
}; // Animal
class Mammal : public Animal {
public:
virtual std:string speak() = 0;
protected:
Mammal( int age, float weight ) : Animal( AnimalType::MAMMAL, age, weight ) {}
}; // Mammal
class Dog : public Mammal {
public:
Dog( int age, float weight ) : Mammal( age, weight ) {}
virtual ~Dog() {}
std::string speak() { return std::string( "rough" ); }
}; // Dog
在这里的第二种情况下,Animal 和 Mammal 都不能从其他地方构造为对象,但 Dog 可以。这是由于受保护的构造函数。这里 Animal 和 Mammal 都代表一个概念而不是一个对象,但 Dog 确实代表一个对象。希望对您有所帮助。