如果我想避免它的实例,是否保护基类构造函数是一种好习惯?我知道我可以使用纯虚拟虚拟方法,但这看起来很奇怪......
请考虑以下代码:
#include <iostream>
using std::cout;
using std::endl;
class A
{
protected:
A(){};
public:
virtual void foo(){cout << "A\n";};
};
class B : public A
{
public:
void foo(){cout << "B\n";}
};
int main()
{
B b;
b.foo();
A *pa = new B;
pa->foo();
// this does (and should) not compile:
//A a;
//a.foo();
return 0;
}
我有没有看到缺点或副作用?
答案 0 :(得分:4)
通常的做法是使基类构造函数受到保护。当你的基类中有一个纯虚函数时,这不是必需的,因为你无法实例化它。
但是,在基类中定义非纯虚函数不被视为良好实践,但在很大程度上取决于您的用例并且不会造成损害。
没有任何不利或副作用。使用受保护的构造函数,您只需告诉其他开发人员您的类仅用作基础。
答案 1 :(得分:2)
您想要实现的通常是通过析构函数而不是构造函数来完成,因为您可以使用该函数控制所需的行为,而不必使用您编写的每个新构造函数来处理它。
是一种常见的编码风格/指南您选择后两者中的哪一项是设计决定,无法从您的问题中回答。
答案 2 :(得分:1)
它可以满足您的要求。
但是我不确定你用它获得了什么。有人可以写
struct B : A {
// Just to workaround limitation imposed by A's author
};
通常情况下,不是将无意义的纯虚函数添加到基类中......而是存在纯虚函数,其基本级别无法提供有意义的实现,这就是为什么它们最终成为纯虚函数的原因。
无法实例化该类是一个很好的额外属性。
答案 3 :(得分:0)
使析构函数纯粹虚拟。每个类都有一个析构函数,基类通常应该有一个虚析构函数,因此你不会添加一个无用的虚函数。
请注意,纯虚拟析构函数必须具有函数体。
class AbstractBase
{
public:
virtual ~AbstractBase() = 0;
};
inline AbstractBase::~AbstractBase() {}
如果您不希望将析构函数体放在头文件中,请将其放在源文件中并删除内联关键字。