我有以下两难境地:
我有一个完整的抽象课。每个继承类都需要3个相同的参数。它们中的每一个都需要额外的其他特定参数。
我可以:
1)在我的基类中实现一个公共构造函数来初始化3个公共参数,但是我必须为相应的字段创建非抽象的getter(它们是私有的)。
或
2)让我的基类保持抽象,并在继承的类中实现构造函数,但之后我必须在每个类字段中创建通用参数。
哪种方法更好?我不想使用受保护的成员。
发布于 2016-02-18 21:42:17
抽象类是指至少有一个纯虚拟(或您所称的抽象)函数的类。拥有非抽象、非虚函数并不会改变你的类是抽象的事实,只要它至少有一个纯虚函数。在你的基类中拥有通用的功能,即使它是抽象的。
发布于 2016-02-18 21:43:57
如果你的类看起来像这样,一个纯粹的抽象类:
class IFoo {
public:
virtual void doThings() = 0;
}
class Foo {
public:
Foo(std::string str);
void doThings() override;
}继承的价值在于为您提供了在运行时用另一个Foo替换Foo的机会,但在接口后面隐藏了具体的实现。你不能在构造函数中使用这种优势,没有虚拟构造函数(这就是像Abstract Factory Pattern这样的东西存在的原因)。您的所有Foo实现都采用std::string,而您的所有doThings实现都使用该字符串?很好,但这是巧合,不是合同,也不属于IFoo。
让我们来讨论一下您是否已经用IFoo创建了具体的实现,这样它就是一个抽象类,而不是一个纯粹的抽象类(顺便说一句,IFoo现在可能不是一个好名字)。(*1)假设使用继承来共享行为对于你的类来说是正确的选择,有时是正确的。如果该类有需要初始化的字段,则创建一个protected构造函数(从每个子实现中调用)并删除/省略默认的构造函数。
class BaseFoo {
private:
std::string _fooo;
protected:
BaseFoo(std::string fooo) : _fooo(fooo) {}
public:
virtual void doThings() = 0;
std::string whatsTheBaseString() { return _fooo;}
}上面是你从子构造函数中正确传递基类所需字段的方法。这是一个编译时保证,子类将“记住”正确地初始化_fooo,并避免将实际的成员fooo暴露给子类。在这里,尝试直接在所有子构造函数中初始化_fooo是不正确的。
*1)很快,为什么?Composition may be a better tool here?。
发布于 2016-02-18 21:49:57
避免代码重复的一种方法是引入额外的继承级别,而不会污染数据成员的抽象接口:
// Only pure virtual functions here
class Interface {
public:
virtual void foo() = 0;
};
// Things shared between implementations
class AbstractBase : public Interface {
};
class ImplementationA : public AbstractBase {
};
class ImplementationB : public AbstractBase {
};https://stackoverflow.com/questions/35482946
复制相似问题