纯虚函数
问题描述:
最近我读在C++中一些关于纯虚函数的概念,我不知道,因为下面的代码:纯虚函数
class First
{
public:
virtual void init() = 0;
protected:
bool initialized;
};
class Second : public First
{
public:
void init() { ((*someting*) ? (initialized=true) : (initialized=false));
};
如果First
类的创作者想要确保init()
MUST的执行设置initialized
变量是真是假他们怎么能这样做?是否有强制执行纯虚函数来设置从基类继承的任何变量的选项?
答
您可以让init
受保护并返回bool
。 然后有一个新的initialize
方法是公开的,也设置initialized
成员。
由于init
现在有一个返回值,它必须由实现派生类的任何人设置。
class First
{
public:
void initialize() { initialized = init(); }
protected:
virtual bool init() = 0;
bool initialized;
};
class Second : public First
{
public:
bool init() { return (*something*); }
};
答
你不能检查,如果initialized
已设置与否,因为它不能代表第三状态“不确定”。
溶液1
保护纯虚函数,使其返回初始值,并经由非虚拟包装
class First
{
public:
void init()
{
initialized = initImplementation();
// check initialized here
}
protected:
virtual bool initImplementation() = 0;
bool initialized;
};
溶液2
变化初始化调用它枚举状态为未定义,未初始化,初始化,保护纯虚函数并通过非虚包装调用它,t然后帽子检查,如果变量已设置:
class First
{
public:
void init()
{
initImplementation();
// check initialized here
}
protected:
virtual void initImplementation() = 0;
enum
{
undefined,
initialized,
uninitialized
} initialized;
};
解决方案3
摆脱初始化,只是抛出一个异常,在init()
,如果出现错误。来电者会知道发生了问题。作为一个旁注,你也可以从构造函数中抛出。
答
那么,而你的问题的直接回答是没有。您可以使用一些技巧来获得您的init
功能的保证电话。 比方说,你有下面的基类:
class Base
{
public:
virtual void init() = 0;
private:
bool initialized = false;
};
void Base::init()
{
std::cout << "Called from base!\n";
initialized = true;
}
及以下得出:
class Derived: public Base
{
friend class Enforcer<Derived>;
public:
void init() override
{
std::cout << "Called from derived!\n";
}
private:
Derived()
{
}
private:
using BaseClass = Base;
};
看私人构造函数和友元声明:您可以在不的帮助没有更多的创建这个类Enforcer
class(这一步并非真正需要,但它会真正强制Derived
类的任何用户使用Enforcer
)。现在,我们需要写Enforcer
类,那就是:
template<typename T>
class Enforcer: public T
{
public:
template<typename... Args>
Enforcer(Args&&... arg): T(std::forward<Args>(arg)...)
{
}
void init() override
{
T::init();
T::BaseClass::init();
}
};
在ideone整个例子。
是的,它有它的缺点(你需要添加一些额外的东西到Derived
类),但它在我看来非常整齐地解决了这个需求。
_“是否有强制执行纯虚函数来设置从基类继承的任何变量的选项?”_编号 –
您可以做的是在声明它时将bool成员设置为false(或true) (在基类中) – sop
可惜...无论如何,@πάνταῥεῖ - 感谢您的快速回答! – michelson