Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 以基类为参数的派生类构造函数(这是一种好的做法吗?)_C++_Oop_Constructor - Fatal编程技术网

C++ 以基类为参数的派生类构造函数(这是一种好的做法吗?)

C++ 以基类为参数的派生类构造函数(这是一种好的做法吗?),c++,oop,constructor,C++,Oop,Constructor,下面我有两个简单的类,一个是基类,另一个是从基类派生的类 在派生类中有两个构造函数,一个接受基类和派生类所需的所有参数,另一个接受基类引用本身作为参数 我知道将基类引用作为参数的构造函数不是一个好的实践 然而,我想知道为什么这不是一个好的做法? 它实现了与其他构造函数相同的功能 有人能解释一下为什么这不是一个好的OOP实践吗 class Base { public: Base(int a, int b): m_a(a), m_b(b) {}

下面我有两个简单的类,一个是基类,另一个是从基类派生的类
在派生类中有两个构造函数,一个接受基类和派生类所需的所有参数,另一个接受基类引用本身作为参数

我知道将基类引用作为参数的构造函数不是一个好的实践
然而,我想知道为什么这不是一个好的做法? 它实现了与其他构造函数相同的功能

有人能解释一下为什么这不是一个好的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()

这将完美地编译

在c++-11中,您还可以为
m_c
数据成员设置默认值。比如说

int m_c = 0;

因此,从
Base
继承的构造函数将使
派生的
保持一致状态

我相信您展示的代码是不错的OOP实践。由于
派生的
使用公共继承,因此
派生的
用户知道并有权访问
。因此,您没有添加任何依赖项,因此也没有使任何内容变得更具限制性或更复杂

这就是说,即使
Derived
使用的是受保护继承或私有继承,根据
Derived
的用户是否知道class
Base
,这也不一定是不好的做法

想象一下:

class Derived { // no inheritance
public:
    void doSomething(const X& b); // `X` could be `Base`, `Foo`, or `std::string` for that matter...
};

你能称之为上述不良行为吗?我想不是。这里的关键是,正如您所展示的代码(假设您将const限定符添加到Base&正如lrleon所建议的那样)使用
Base
作为值类型<代码>派生的没有保存对传入的基本对象的指针/引用,因此您使用的是正常的参数传递,关于参数传递没有任何异常或不好的做法。

您从哪里发现这不是一个好的做法?我想这主要取决于您的设计。若
Derived
Base
的扩展或包装,那个么为什么不呢!但我想它可能会在实现中引起一些麻烦,主要是如果您使用指针,而不是每次都复制所有内容(只需要小心并了解
Base
)的实现。我认为,如果您可以将
派生的
视为独立于
基础
的东西,或者您想隐藏实现,那么这种做法就不太好了。我理解您的意思,但这不是我想要的。几乎所有的C++教程或书籍都指定了派生的所有基础参数和初始化基本成员,我想知道为什么/不应该派生类作为参数。现在可以认为它不是有效的代码,因为额外的拷贝,但这是一个不同的问题。
class Derived { // no inheritance
public:
    void doSomething(const X& b); // `X` could be `Base`, `Foo`, or `std::string` for that matter...
};