必须设置变量的纯虚函数
Pure virtual function which must set variable
最近我读了一些关于 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()
必须设置变量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
将初始化更改为状态未定义、未初始化、已初始化的枚举,保护纯虚函数并通过非虚拟包装器调用它,然后检查变量是否已设置:
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;
};
看看私有构造函数和 friend 声明:如果没有 Enforcer
类的帮助,你就不能再创建这个类了(这一步并不是真正必需的,但它确实会强制 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
类添加一些额外的东西),但在我看来,它非常巧妙地解决了这一要求。
相关文章:
- 未使用的C++未优化的静态成员函数/变量
- 内联函数/变量的外部链接
- 同一函数中的静态函数变量初始化顺序
- 将非静态成员函数C 的使用无效,而将成员功能作为函数变量
- 如何从doxygen输出中排除类的无证件成员函数/变量
- 如何在LUA C API中分配全局LUA函数变量
- 如何将函数变量传递给C lambda函数
- 通过另一个C++函数更改函数变量
- c++11 lambda 真的支持闭包吗?函数变量中存在语义冲突
- C++:静态成员不能在声明时定义,但静态函数变量可以?
- apache-frift是否支持函数变量作为参数
- 类函数/变量在使用之前必须声明
- 函数变量去哪里
- 无法使用函数变量?错误表达式必须具有类类型
- 如何在main中使用函数变量
- 每当尝试打印函数变量时,C++ cout 错误
- 是否存在查看成员函数/变量的整洁等效项
- 访问友元类之间的函数变量
- 函数到函数变量
- 一个定义规则是否强制创建一个静态函数变量