假设我有一个界面层次结构:
class A
{
virtual void commonFunc() = 0;
};
class B1 : public A
{
virtual void b1SpecificFunc() = 0;
};
class B2 : public A
{
virtual void b2SpecificFunc() = 0;
};
仅存在接口A以避免重复commonFunc()函数。
现在,如果我想实现这个,以便有2个可实现的类ImplB1和ImplB2,我可以这样做:
class ImplA
{
virtual void commonFunc();
};
class ImplB1 : public ImplA
{
virtual void b1SpecificFunc();
};
class ImplB2 : public ImplA
{
virtual void b2SpecificFunc();
};
这个问题是它让ImplA变得不稳定,我不想这样做。我只希望ImplB1和ImplB2是可实现的,因为ImplA只是存在共同功能的共同点。
我怎么能这样设计呢?谢谢。
答案 0 :(得分:2)
仅存在接口A以避免重复commonFunc()函数。
你的意思是避免重复声明,不是吗?
class ImplA { virtual void commonFunc(); };
这应该是:
class ImplA : public A
{
virtual void commonFunc();
};
我想重点是ImplA
实际上有commonFunc
的实现。所以为了这个答案的简洁,让我们把它放到课堂定义中:
class ImplA : public A
{
virtual void commonFunc() {} // implementation
};
这个问题是它让ImplA变得不稳定。
只需将ImplA
的析构函数设为纯虚拟:
class ImplA : public A
{
public:
virtual ~ImplA() = 0 {}
private:
virtual void commonFunc() {}
};
即使在派生类内也会阻止实例化。功能。例如,以下内容将创建编译器错误:
class ImplB1 : public ImplA
{
public:
virtual void b1SpecificFunc()
{
ImplA a; // error, cannot instantiate abstract class
}
};
实际上,您甚至无法在自己的函数中实例化该类:
class ImplA : public A
{
public:
virtual ~ImplA() = 0 {}
private:
virtual void commonFunc()
{
ImplA a; // error, cannot instantiate abstract class
}
};
但严重的是,这一切似乎都非常过度设计。也许您真正需要的是使commonFunc
成为A
的非虚拟保护函数,派生类可以在需要时调用它们。
或许commonFunc
可能只是一个独立的效用函数?
答案 1 :(得分:0)
您可以执行以下操作。此外,这里有一个SO question/answer。
注意:当我回答你可以做到这一点的问题时我并没有断言你应该做什么。< / p>
#include <iostream>
class A
{
public:
virtual void commonFunc() = 0;
};
void A::commonFunc() // Pure virtual but implemented anyway
{
// Derived classes can explicitly opt-in to this implementation
std::cout << "A::commonFunc()\n";
}
class B1 : public A
{
public:
virtual void b1SpecificFunc() = 0;
};
class B2 : public A
{
virtual void b2SpecificFunc() = 0;
};
class ImplB1 : public B1
{
public:
// This function must be implemented because its declared pure virtual
virtual void commonFunc()
{
// Can override the behavior if desired...
A::commonFunc(); // Explicitly use default implementation
}
virtual void b1SpecificFunc()
{
std::cout << "b1SpecificFunc()\n";
}
};
class ImplB2 : public B2
{
public:
// This function must be implemented because its declared pure virtual
virtual void commonFunc()
{
// Can override the behavior if desired...
A::commonFunc(); // Explicitly use default implementation
}
virtual void b2SpecificFunc()
{
std::cout << "b2SpecificFunc()\n";
}
};
int main()
{
//A a; // Won't compile (as expected/desired)
ImplB1 b1;
ImplB2 b2;
b1.commonFunc();
b1.b1SpecificFunc();
b2.commonFunc();
b2.b2SpecificFunc();
return 0;
}
A::commonFunc()
b1SpecificFunc()
A::commonFunc()
b2SpecificFunc()