派生类构造函数以基类为参数(这是好的做法吗?
Derived class constructor taking base class as argument (Is it Good practice?)
我下面有两个简单的类,一个是基础类,另一个是从它派生出来的。
在派生类中有两个构造函数,一个采用 base 和 derived 所需的所有参数,另一个采用 Base 类引用本身作为参数。
我知道将基类引用作为参数的构造函数不是一个好的做法。
但是,我想知道为什么它不被认为是一种好的做法?它实现了与其他构造函数相同的目标。
有人可以澄清为什么这不是一个好的 OOP 实践吗?
class Base
{
public:
Base(int a, int b):
m_a(a),
m_b(b)
{}
Base(const Base& b):
m_a(b.m_a),
m_b(b.m_b)
{}
~Base() {}
protected:
int m_a;
int m_b;
};
class Derived : public Base
{
public:
// Constructor which takes base class argument and initializes base
Derived(Base &base, int c):
Base(base),
m_c(c)
{}
Derived(int a, int b, int c):
Base(a, b),
m_c(c)
{}
~Derived() {}
private:
int m_c;
};
int main()
{
Base base(1,2);
Derived derived1(base, 3); //
Derived derived2(1,2, 3);
}
有必要知道在其中指定第一个派生构造函数的上下文。
但是,也许使用 const Base
参数定义它会更优雅。像这样:
Derived(const Base &base, int c):
Base(base),
m_c(c)
{}
因此,它告诉编译器保护base
对象的状态。
此外,如果您使用的是 c ++ - 11,那么您可能有兴趣声明:
using Base::Base;
在 Derived
类中,是什么使该Derived
继承了 Base
的构造函数。 因此,您可以在main()
中添加:
Derived derived3(1,2);
这将完美地编译。
在 c++-11 中,您还可以为m_c
数据成员设置默认值。
int m_c = 0;
因此,从Base
继承的构造函数将使Derived
处于一致状态
你展示的代码不是糟糕的 OOP 实践。Derived
的用户知道并有权访问Base
,因为Derived
使用公共继承。因此,您不会添加任何依赖项,因此不会使任何内容更具限制性或复杂性。
也就是说,即使Derived
使用受保护或私有继承,也不一定是不好的做法,这取决于Derived
的用户是否知道类Base
。
想象一下:
class Derived { // no inheritance
public:
void doSomething(const X& b); // `X` could be `Base`, `Foo`, or `std::string` for that matter...
};
你会说上述做法不好吗?我认为不是。这里的关键,就像你提供的代码一样(假设你按照lrleon的建议将const限定符添加到Base&),是你正在使用Base
作为值类型。 Derived
没有持有指向要传入的基本对象的指针/引用,因此您拥有的是正常的参数传递,并且参数传递没有任何异常或不良做法。
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 参数包构造函数在类模板中隐藏用户定义的转换
- 具有已删除移动和复制构造函数的类的就地构造
- 创建一个没有复制构造函数的类的 std::vector 的 std::vector
- C++构造函数和类?
- 在 C++ 中,默认情况下构造函数为类的数据成员提供的值是多少?
- 如何在其他类中使用参数化构造函数制作类的对象?
- 具有值包装器的可变参数模板构造函数的类构造函数优先级
- 如何使用私有构造函数对类进行单元测试?
- C++虚拟函数:基类函数是调用的,而不是派生的
- c++17在编译时将带有已删除复制构造函数的类添加到std::vector
- 从作为模板参数传递给构造函数的类继承,或者从它们继承
- 继承的构造函数忽略类内初始化
- 模板和隐式构造函数的类定义之外的友元声明
- 具有字符串文本构造函数的类不适用于 const 引用初始化
- 为什么具有私有构造函数的类不阻止从此类继承?如何控制哪些类可以从某个基继承?
- 具有多个非默认构造函数基的Singleton派生类
- 调用基默认构造函数模板类
- 当基类未指定构造函数时,如何使用仅具有带参数的构造函数的类派生基类?
- 构造所有基类不需要默认生成的构造函数