我创建了扩展C ++中其他接口的接口(抽象类),我试图实现它们,但是在编译时会出现错误。
以下是错误:
main.cpp: In function 'int main()':
main.cpp:36:38: error: cannot allocate an object of abstract type 'Subclass'
Subclass * subObj = new Subclass();
^
Subclass.h:13:7: note: because the following virtual functions are pure within 'Subclass':
class Subclass : SubInterface {
^
SuperInterface.h:13:18: note: virtual void SuperInterface::doSomething()
virtual void doSomething()=0;
以下是我的消息来源:
#include <iostream>
class SuperInterface {
public:
virtual void doSomething() = 0;
protected:
int someValue;
};
class SubInterface : public SuperInterface {
public:
virtual void doSomethingElseThatHasNothingToDoWithTheOtherMethod() = 0;
protected:
int anotherValue;
};
class Superclass : public SuperInterface {
public:
Superclass() {}
virtual ~Superclass() {}
void doSomething() {std::cout << "hello stackoverflow!";}
};
class Subclass : public SubInterface {
public:
Subclass() {}
virtual ~Subclass() {}
void doSomethingElseThatHasNothingToDoWithTheOtherMethod() {std::cout << "goodbye stackoverflow!";}
};
int main(void)
{
Superclass * superObj = new Superclass();
Subclass * subObj = new Subclass();
}
这就是我想要的:
我希望我的实现能够识别,因此具有与已经覆盖的方法相同的行为(例如,subObj->doSomething()
方法无需再次实现它就可以工作)。任何人都可以告诉我,如果可能的话,我应该做些什么来实现这一目标?感谢。
答案 0 :(得分:2)
您收到错误是因为您正在尝试创建抽象类的对象。
由于此行Subclass
,您的void doSomethingElse()=0;
是一个抽象类。
如果一个类有一个纯虚函数,它将是一个抽象类。你不能创建一个抽象类的对象,你只能有一个引用或指向它的指针。
要摆脱错误,doSomethingElse
中Subclass
的声明应为
void doSomethingElse();
而不是void doSomethingElse()=0;
此外,我不明白为什么你需要两个接口。您可以从Subclass
派生SuperInterface
,因为它基本上与SubInterface
答案 1 :(得分:2)
不,你不能通过简单的继承做你想做的事。 Subclass在任何时候都不会继承或提供doSomething()
的实现,因此您无法根据需要调用subObj->doSomething()
。您必须遵守subInterface
。
您可以从Subclass
和Superclass
继承Subinterface
,只需将doSomething()
实现为一种代理Superclass::doSomething()
。你仍然需要一个实现,但你不必“重新实现”它。
答案 2 :(得分:0)
你的类'Subclass'应该覆盖2个纯虚方法,所以:
class Subclass : SubInterface {
public:
Subclass();
virtual ~Subclass();
void doSomethingElse() override;
void doSomething() override;
};
不这样做或说明
void doSomethingElse()= 0;
class Subclass也变得抽象,无法实例化。您可以查看:http://www.parashift.com/c++-faq-lite/pure-virtual-fns.html
这就是我想要的:我希望我的实现能够意识到这一点 与已经覆盖的方法相同的行为(例如 subObj-&gt; doSomething()方法无需实现即可运行 再次)。任何人都可以告诉我如果要做到这一点我应该做些什么 它甚至可能!! ??感谢。
- &GT;也许声明方法虚拟而不是虚拟
答案 3 :(得分:0)
说实话,我并非完全确定您的设计想要表达的内容,但此处至少存在两个技术错误:
1。)在所有情况下都使用私有继承,因此您实际上根本不处理“接口”。公共继承是这样实现的:
class SubInterface : public SuperInterface
2。)您使用=0
来表示您想要实现的功能。
这将修复编译器错误,但设计仍然值得怀疑。考虑到你在问题结束时给出的动机,我推荐组合而不是(公共)继承。在C ++中,共享功能最好用组合表达。简而言之,将常用功能封装在一个单独的类中,并为其他类配备一个对象。
class CommonFunctionality
{
//...
public:
void doSomething();
void doSomethingElse();
};
class SuperClass
{
//...
private:
CommonFunctionality m_functionality;
};
class SubClass : public SuperClass
{
//...
private:
CommonFunctionality m_functionality;
};
事实上,也许你甚至不需要 来为CommonFunctionality创建一个类。也许简单的独立功能会做。具有Java背景的程序员(并且您的代码看起来有点像)倾向于将太多东西放入类中而不是C ++中所需的东西。
答案 4 :(得分:0)
有两个问题,编译器明确说明了这些问题:
问题1
SubInterface::doSomethingElse()()
中的{p> Subclass
被声明为纯虚拟,无视您尝试在源文件中定义它(我很确定,这是一种复制粘贴错误)。< / p>
class Subclass : SubInterface
{
public:
Subclass();
virtual ~Subclass();
void doSomethingElse() = 0; // still pure?
};
解决方案很明显:
class Subclass : SubInterface
{
public:
Subclass();
virtual ~Subclass();
virtual void doSomethingElse() override
{
}
};
(这里使用C ++ 11 override
说明符,因此编译器将检查覆盖的正确性;它不是强制性的)
问题2
doSomething()
甚至没有尝试覆盖,无论是SuperInterface
还是Subclass
,所以它都保持纯虚拟。虽然在doSomething()
中覆盖了Superclass
,但Subclass
却不知道Superclass
的存在。
解决方案:覆盖doSomething()
或SuperInterface
或Subclass
的任何子项中的Subclass
(尚未拥有它们)。例如,覆盖Subclass
:
class Subclass : SubInterface
{
public:
Subclass();
virtual ~Subclass();
virtual void doSomething() override
{
}
virtual void doSomethingElse() override
{
}
};
其他问题:
您正在继承没有可见性说明符,即privat
ely。使用public
继承直到您确实需要其他内容:
class Derved : public Base {};
您的源文件扩展名为.c
,但包含C ++代码。如果您没有通过命令行参数明确声明编程语言,这可能会使一些编译器感到困惑。按照惯例,大多数程序员使用.cpp
扩展名,大多数编译器将这些文件视为C ++源文件。