C 中的继承:在亲子类中定义变量
Inheritance in C++: define variables in parent-child classes
问题
我正在寻找定义亲子类中变量的最佳方法,以便通过指向其父班的指针来调用。
这是原始的:
class Base {
public:
virtual void function() = 0;
};
class A : public Base {
public:
int a, b;
A(int a_, int b_) : a(a_), b(b_) {};
void function() { // do something.. }
};
class B : public Base {
public:
int a, b;
B(int a_, int b_) : a(a_), b(b_) {};
void function() { // do something.. }
};
Base* elements[2] = {
new A(1,2),
new B(3,4)
};
由于我在两个构造函数中定义了a, b
,因此我可以在抽象类Base
中定义它们。这样,代码应该更有效,更干净。这种做法正确吗?我应该如何定义它们?
可能的解决方案
我想到的解决方案是实现一个函数,例如返回a
这样的函数:
class Base {
public:
virtual int return_a() = 0;
};
class A : public Base {
public:
int a, b;
A(int a_, int b_) : a(a_), b(b_) {};
int return_a() {
return a;
}
};
int main(){
int a = elements[0]->return_a();
}
这有效,但我相信这不是一种有效的方法。在抽象类中定义a, b
更好吗?谢谢
这种做法正确吗?
我认为这将变成一个基于意见的提问者。如果您的所有派生类都必须包括成员a
和b
,,则在我看来,它们应该是基类的一部分。这样,您可以确保所有派生的类都包括成员a
和b
,并且您(或其他人(将不会承担忘记包括它们的风险。此外,通过将成员包括在基类中,您可以通过不必在每个派生的类中包含它们来保存内存。C 的virtual
为您提供了完成多态性的所有必要工具,这是您创建Base *
数组的情况。
我还建议您将关键字override
用于在派生类中被覆盖的虚拟函数,而派生类的关键字 final
并不意味着成为基础类。您可以阅读使用Scott Meyers Modern C 书中使用这些关键字的好处。
struct Base
{
int a, b;
Base(int a_, int b_) : a(a_) , b(b_)
{;}
virtual void function() = 0;
};
struct A : Base // A can be a base class of another class.
{
A(int a_, int b_) : Base(a_,b_)
{;}
void funtion() // this will compile, but it's not going to override the Base::function()
{;}
};
struct B final : Base // B can never become a base class.
{
B(int a_, int b_) : Base(a_,b_)
{;}
void funtion() override // this won't compile because override will see that we mis-spelled function()
{;}
};
但是,没有C 规则禁止您将成员包括在所有派生的类中。
另外,如果您的所有成员都是public
,则可以使用struct
来避免在类和继承方法中键入public
。
struct Base
{
// all members are public
};
struct Derived : Base // public inheritance by default.
{
// all members are public
};
这在某种程度上是基于意见的,但这是我根据您发布的代码的想法。
由于您已将Base
(从中衍生出所有类(为抽象类,因此您似乎要将其用作接口。
在这种情况下,最好区分接口继承和实现继承。令Base
没有任何数据,这意味着它不需要任何构造函数。
这是Bjarne Stroustrup给出的编码指南之一: When designing a class hierarchy, distinguish between implementation inheritance and interface inheritance
。
给出的原因是:
接口中的实现详细信息使接口变脆;也就是说,使其用户容易在更改实施后必须重新编译。基类中的数据增加了实施基础的复杂性,并可能导致代码的复制。
请注意,如果派生类中的数据为public
。
- 避免在C++中重复子类定义
- 使用子类覆盖基类中定义的函数
- C++ 确保子类为常量提供自定义值
- 如何为定义的情况创建子类?
- 如何在子类中重新定义数组大小?
- 无法使用在子类中定义的虚拟getter实现基类
- 运算符的歧义错误<<自定义 std::ostream 子类中的重载
- 是否有 lint 工具可以检查子类虚拟函数是否与父类定义匹配?
- 使用子类中的类型定义扩展模板类
- 模板化类继承的子类定义中的错误
- 从模板化类中的子类访问定义
- 使用基类构造函数的子类构造函数的大纲定义
- 共享库中非模板基的模板子类导致未定义的符号类型信息'class'链接错误
- 在子类中定义可变参数函数专用化
- 如何使函数返回由子类定义的值?C++
- 子类ConstexPR类以获得不同的用户定义的转换行为
- 为什么要将子类定义为其自己的父类的好友
- 从超类函数返回子类定义
- 如何为子类定义泛型模板化创建函数
- c++超类为子类定义静态成员变量