下面有两个简单的类,一个是基础,另一个是从它派生的。
在派生类中有两个构造函数,一个获取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);
}
答案 0 :(得分:0)
有必要知道指定第一个Derived构造函数的上下文。
但是,使用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
处于一致状态
答案 1 :(得分:0)
我相信你展示的代码是而不是糟糕的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...
};
。
想象一下:
Base
你会打电话给上面的不良做法吗?我想不是。这里的关键,就像你提供的代码一样(假设你将const限定符添加到Base& lrleon建议),就是你使用Derived
作为值类型。 public static int countHi(String str){
if(str.length() > 0){
if(str.contains("hi")){
return countHi(str.replaceFirst("hi","")) + 1;
}
}
return 0;
}
没有持有对传入的基础对象的指针/引用,所以你所拥有的是正常的参数传递,并且没有关于参数传递的异常或不良做法。