我在头文件中遇到了以下代码:
class Engine
{
public:
void SetState( int var, bool val );
{ SetStateBool( int var, bool val ); }
void SetState( int var, int val );
{ SetStateInt( int var, int val ); }
private:
virtual void SetStateBool(int var, bool val ) = 0;
virtual void SetStateInt(int var, int val ) = 0;
};
Run Code Online (Sandbox Code Playgroud)
对我来说,这意味着Engine从它派生的类或类必须为那些纯虚函数提供实现.但我不认为派生类可以访问这些私有函数以重新实现它们 - 那么为什么要将它们变为虚拟?
众所周知,有些语言有接口的概念.这是Java:
public interface Testable {
void test();
}
Run Code Online (Sandbox Code Playgroud)
如何以最紧凑的方式在C++(或C++ 11)中实现这一点并且代码噪声很小?我很欣赏一个不需要单独定义的解决方案(让标题足够).这是一个非常简单的方法,即使我发现越野车;-)
class Testable {
public:
virtual void test() = 0;
protected:
Testable();
Testable(const Testable& that);
Testable& operator= (const Testable& that);
virtual ~Testable();
}
Run Code Online (Sandbox Code Playgroud)
这只是一个开始......而且已经超过了我想要的时间.怎么改进呢?也许在std命名空间的某个地方有一个基类专为此而设计?
类层次结构的一个常见错误是将基类中的方法指定为虚拟,以便继承链中的所有重写都能完成某些工作,并且忘记将调用传播到基本实现.
class Container
{
public:
virtual void PrepareForInsertion(ObjectToInsert* pObject)
{
// Nothing to do here
}
};
class SpecializedContainer : public Container
{
protected:
virtual void PrepareForInsertion(ObjectToInsert* pObject)
{
// Set some property of pObject and pass on.
Container::PrepareForInsertion(pObject);
}
};
class MoreSpecializedContainer : public SpecializedContainer
{
protected:
virtual void PrepareForInsertion(ObjectToInsert* pObject)
{
// Oops, forgot to propagate!
}
};
Run Code Online (Sandbox Code Playgroud)
我的问题是:是否有一种好的方法/模式来确保在调用链的末尾始终调用基本实现?
我知道有两种方法可以做到这一点.
您可以使用成员变量作为标志,将其设置为虚方法的基本实现中的正确值,并在调用后检查其值.这需要使用公共非虚方法作为客户端的接口,并使虚方法受到保护(这实际上是一件好事),但它需要专门为此目的使用成员变量(需要如果虚方法必须是const,则是可变的.
class Container
{
public:
void PrepareForInsertion(ObjectToInsert* pObject)
{
m_callChainCorrect = false;
PrepareForInsertionImpl(pObject); …Run Code Online (Sandbox Code Playgroud) 我正在尝试实现命令设计模式,但我遇到了一个概念问题.假设您有一个基类和一些子类,如下例所示:
class Command : public boost::noncopyable {
virtual ResultType operator()()=0;
//Restores the model state as it was before command's execution.
virtual void undo()=0;
//Registers this command on the command stack.
void register();
};
class SomeCommand : public Command {
virtual ResultType operator()(); // Implementation doesn't really matter here
virtual void undo(); // Same
};
Run Code Online (Sandbox Code Playgroud)
问题是,每次()在SomeCommand实例上调用操作符时,我都想通过调用Command的register方法将*this添加到堆栈中(主要用于撤消).我想避免从SomeCommand :: operator()()调用"register",但要将它命名为automaticaly(someway ;-))
我知道当你构造一个像SomeCommand这样的子类时,基类构造函数被称为automaticaly,所以我可以在那里添加一个"register"调用.在调用operator()()之前,我不想调用它.
我怎样才能做到这一点?我想我的设计有些缺陷,但我真的不知道如何使这项工作.
我在库中找到了以下代码:
class Bar {
public:
bool foo(int i) {
return foo_(i);
}
private:
virtual bool foo_(int i) = 0;
};
Run Code Online (Sandbox Code Playgroud)
现在我想知道:你为什么要使用这个间接?可能有任何理由说明为什么上述会比简单的替代方案更好:
class Bar {
public:
virtual bool foo(int i) = 0;
};
Run Code Online (Sandbox Code Playgroud) C++私有和受保护的虚方法,有没有使用公共虚方法的正当理由?正在讨论非虚拟接口(NVI)和非公共虚拟功能及其共生关系.Scott Meyers也在Effective C++中说过
有时虚拟功能甚至必须是公开的,但是NVI惯用法无法真正应用.
我没有看到为什么NVI 要求特定于实现的虚拟功能是非公开的?从Herb Sutter的文章Virtuality来看,它是一个很好的做法,例如,将公共(客户端)接口与实现细节(非公共接口)分开是很好的.我想知道的是,如果有任何语言功能我错过了语义上会阻止NVI被应用,如果这些虚拟功能被公开?
例如:
class Engine
{
public:
void SetState( int var, bool val );
{ SetStateBool( int var, bool val ); }
void SetState( int var, int val );
{ SetStateInt( int var, int val ); }
private:
virtual void SetStateBool(int var, bool val ) = 0;
virtual void SetStateInt(int var, int val ) = 0;
};
Run Code Online (Sandbox Code Playgroud)
如果我把带来哪些影响SetStateBool,并SetStateInt在类定义的公共部分?
c++ ×6
inheritance ×3
abstract ×1
base-class ×1
c++11 ×1
class ×1
function ×1
idioms ×1
interface ×1
methods ×1
oop ×1
polymorphism ×1
virtual ×1