抽象类中的公共构造函数是一个代码吗?使构造函数受到保护可提供您可以使用的所有访问权限。使其公开的唯一附加访问权限是允许将类的实例声明为无法访问其受保护成员的范围中的变量,但是根本不能声明抽象类的实例。
我的观点是公共构造函数可能会被视为令人困惑,正如你所说,保护它是正确的。我会说受保护的构造函数正确地强化了这样一种印象,即抽象类的唯一合理用法是从它派生出来。
实际上,如果需要执行某些操作,您只需要在抽象类中声明构造函数,例如。初始化自己的私人成员。我希望有其他受保护的成员函数对派生类有帮助。
编辑:
由于没有人发布过任何代码而且@sbi在对OP的评论中要求提供一些代码,我想我会发布一些代码:
class Base:
{
public: // The question is: should the ctor be public or protected?
// protected:
Base():i(0){} // ctor is necessary to initialise private member variable
public:
virtual ~Base(){} // dtor is virtual (but thats another story)
// pure virtual method renders the whole class abstract
virtual void setValue(void)=0;
protected:
int getValue(void){ return i;}
private:
int i;
};
Base b1; // Illegal since Base is abstract, even if ctor is public
Base& b2=makeBase(); //We can point to, or refer to a Base
b2.setValue(); // We're not sure what this does, but we can call it.
b2.getValue(); // Illegal since getValue is protected
我已经在至少一个编码指南中读到它,抽象类的构造函数不应该公开 - 我认为这个规则对你给出的原因有意义。
但是,我无法想象将其公开会导致出错的情况。所以我不会说这是代码味道。我将受保护的构造函数视为“很高兴”属性:)
正如您所说,如果您提供公共构造函数,则无需提供抽象类的公共构造函数,也不会被滥用。
但是,您可以考虑将构造函数声明为public,作为用于构造从抽象类派生的类的recomendation。
由于它声明的纯虚方法,抽象类永远不能直接实例化。因此,将构造函数声明为受保护只会为程序员添加额外的提示。
我看到建议在Google风格指南中将构造函数声明为受保护的here。我在其他一些公司编码标准中也遇到了类似的建议。所以这看起来是一个很好的做法。
我知道很多人显然不同意,但我不认为应该保护抽象类ctor,除非你设计的接口有一个特定的原因,所有派生类也有一个受保护的ctor。
原因是当你设计一个抽象类时,你正在设计一个由派生类实现的接口。派生类应该完全按照基类中的设计实现接口。抽象基类提供的接口是契约;不要违反合同。
或者换句话说,如果您正在更改界面,那么您为什么首先从该类派生?
这是一个宗教回答,但是到底是什么。 ;-)
不过我在这里碰到一个旧线程:
public
和protected
构造函数之间的差异时出现的第一个问题,抽象类中的public
构造函数不是代码气味。由于继承构造函数的访问修饰符的工作方式,使用public
与protected
构造函数不等效。抽象类中的public
构造函数添加了比protected
更多的访问权限。
标准草案N4659,10.3.3 / 19规定:
由using声明创建的同义词具有成员声明的通常可访问性。命名构造函数的using-declarator不会创建同义词;相反,如果在用于构造相应基类的对象时可以访问附加构造函数,则可以访问这些附加构造函数,并忽略using-declaration的可访问性。
此行为与C ++ 11中的using-declarators一起引入,有关更多详细信息,请参阅this question。
这是一个最小的例子[godbolt]:
class AbstractPublicCtor {
public:
virtual void foo() = 0;
AbstractPublicCtor(int) {}
};
class AbstractProtectedCtor {
public:
virtual void foo() = 0;
protected:
AbstractProtectedCtor(int) {}
};
class PublicCtor : public AbstractPublicCtor {
public:
using AbstractPublicCtor::AbstractPublicCtor;
void foo() override {}
};
class ProtectedCtor : public AbstractProtectedCtor {
public:
using AbstractProtectedCtor::AbstractProtectedCtor;
void foo() override {}
};
int main() {
PublicCtor x(5); // works
ProtectedCtor y(6); // fails to compile
}
public
构造函数,则使用public
构造函数,并且基类构造函数是实现者的public
构造函数的合适候选者。protected
构造函数(例如,当使用工厂构造实现者时)。注意:这是我个人的意见,我很乐意在评论中讨论它。
出于几个原因,我说这是一个不好的迹象。
首先,它可能误导某人认为他们实际上可以称之为常规。
第二是它暗示作者认为你可以称之为。你现在不知道这是否是他设计的重要部分。