C++ 通过接口使用一个 class 继承自其他几个接口
C++ Using through an interface a class that inherits from several others
我正在学习 C++,我对多重继承和接口感到困惑 classes。
我想要一个 class 继承自其他几个。另外,我想通过接口使用派生的 class 。所以我想,派生 class 应该扩展基础 classes,而派生接口应该扩展基础接口。我会用其他语言做到这一点,但我认为 C++ 不能那样工作。
这是我认为应该有效的代码:
#include <iostream>
using std::cout;
using std::endl;
class
Base1Itf
{
public:
virtual void blue() = 0;
};
class
Base1Abs
:
public Base1Itf
{
public:
void blue()
{
cout << "blue" << endl;
}
};
class
DerivedItf
:
public Base1Itf
{
public:
virtual void red() = 0;
};
class
Derived
:
public Base1Abs,
public DerivedItf
{
public:
void red()
{
cout << "red" << endl;
}
};
int main()
{
DerivedItf* d = new Derived();
d->red();
d->blue();
delete d;
return 0;
}
这是我得到的编译器错误:
src/test.cpp: In function ‘int main()’:
src/test.cpp:49:30: error: invalid new-expression of abstract class type ‘Derived’
DerivedItf* d = new Derived();
^
src/test.cpp:35:2: note: because the following virtual functions are pure within ‘Derived’:
Derived
^~~~~~~
src/test.cpp:10:16: note: virtual void Base1Itf::blue()
virtual void blue() = 0;
^~~~
示例中只实现了一个基础 class,但还会有更多。
我做错了什么?谢谢。
编辑
如果我删除 Base1Itf 的 Base1Abs 继承以避免钻石问题,编译器会显示相同的错误。
这就是众所周知的C++菱形问题。这就是你解决它的方法:
#include <iostream>
using std::cout;
using std::endl;
class Base1Itf {
public:
virtual void blue() = 0;
virtual ~Base1Itf() { }
};
class Base1Abs : virtual public Base1Itf {
public:
void blue() override {
cout << "blue" << endl;
}
virtual ~Base1Abs() { }
};
class DerivedItf : virtual public Base1Itf {
public:
virtual void red() = 0;
virtual ~DerivedItf() { }
};
class Derived : public Base1Abs, public DerivedItf {
public:
void red() override {
cout << "red" << endl;
}
virtual ~Derived() { }
};
int main() {
DerivedItf* d = new Derived();
d->red();
d->blue();
delete d;
return 0;
}
继承中也推荐使用虚析构函数
你看,这里发生的是 classes Base1Abs
和 DerivedItf
都继承了 blue
的副本。现在,当您从这 2 个继承另一个 class Derived
时,那个 class 继承了 blue
的 2 个副本,然后编译器开始想知道要调用哪个副本。因此,您实际上继承了 2 classes,结果只有 blue
的一个副本被继承
我正在学习 C++,我对多重继承和接口感到困惑 classes。
我想要一个 class 继承自其他几个。另外,我想通过接口使用派生的 class 。所以我想,派生 class 应该扩展基础 classes,而派生接口应该扩展基础接口。我会用其他语言做到这一点,但我认为 C++ 不能那样工作。
这是我认为应该有效的代码:
#include <iostream>
using std::cout;
using std::endl;
class
Base1Itf
{
public:
virtual void blue() = 0;
};
class
Base1Abs
:
public Base1Itf
{
public:
void blue()
{
cout << "blue" << endl;
}
};
class
DerivedItf
:
public Base1Itf
{
public:
virtual void red() = 0;
};
class
Derived
:
public Base1Abs,
public DerivedItf
{
public:
void red()
{
cout << "red" << endl;
}
};
int main()
{
DerivedItf* d = new Derived();
d->red();
d->blue();
delete d;
return 0;
}
这是我得到的编译器错误:
src/test.cpp: In function ‘int main()’:
src/test.cpp:49:30: error: invalid new-expression of abstract class type ‘Derived’
DerivedItf* d = new Derived();
^
src/test.cpp:35:2: note: because the following virtual functions are pure within ‘Derived’:
Derived
^~~~~~~
src/test.cpp:10:16: note: virtual void Base1Itf::blue()
virtual void blue() = 0;
^~~~
示例中只实现了一个基础 class,但还会有更多。
我做错了什么?谢谢。
编辑
如果我删除 Base1Itf 的 Base1Abs 继承以避免钻石问题,编译器会显示相同的错误。
这就是众所周知的C++菱形问题。这就是你解决它的方法:
#include <iostream>
using std::cout;
using std::endl;
class Base1Itf {
public:
virtual void blue() = 0;
virtual ~Base1Itf() { }
};
class Base1Abs : virtual public Base1Itf {
public:
void blue() override {
cout << "blue" << endl;
}
virtual ~Base1Abs() { }
};
class DerivedItf : virtual public Base1Itf {
public:
virtual void red() = 0;
virtual ~DerivedItf() { }
};
class Derived : public Base1Abs, public DerivedItf {
public:
void red() override {
cout << "red" << endl;
}
virtual ~Derived() { }
};
int main() {
DerivedItf* d = new Derived();
d->red();
d->blue();
delete d;
return 0;
}
继承中也推荐使用虚析构函数
你看,这里发生的是 classes Base1Abs
和 DerivedItf
都继承了 blue
的副本。现在,当您从这 2 个继承另一个 class Derived
时,那个 class 继承了 blue
的 2 个副本,然后编译器开始想知道要调用哪个副本。因此,您实际上继承了 2 classes,结果只有 blue
的一个副本被继承