有什么方法可以实现抽象 class 的实现,它是 c++ 中其他抽象 classes 的多重继承?
Are there any way to make implementation for abstract class which is multiple inheriting from other abstract classes in c++?
我有两个 'interface' classes:AbstractAccess
和 AbstractPrint
,以及 AbstractRun
class 继承自它们并使用它们的方法.
另外,我有两个接口实现:AbstractAccess
的访问器和 AbstractPrint
的打印
#include <iostream>
using namespace std;
class AbstractAccess {
public:
virtual string access (void) = 0;
};
class AbstractPrint {
public:
virtual void print (string) = 0;
};
class AbstractRun : virtual public AbstractAccess, virtual public AbstractPrint {
public:
void run (void) {
print(access());
}
};
class Accessor : virtual public AbstractAccess {
public:
string access (void){
return name;
}
void setName(string name) {
this->name = name;
}
private:
string name;
};
class Print: public virtual AbstractPrint {
public:
void print (string s) {
cout << s << endl;
}
};
是否有任何方法可以将 AbstractRun
中的接口转换为它们的实现或创建仅使用抽象运行 的 [=23] 的实现 class 运行 =] 方法但具有已实现的接口?
虽然你的问题已经解决了,但我进一步研究了这个问题,我想澄清一些关于继承的困惑。
当您的一个 class 与另一个 class 具有 "is a" 关系时,将使用继承。派生的 class 应该替代您继承自的 class。
在你的例子中,你可以安全地说 class Print
是一个 class AbstractPrint
并且 class Access
同样是一个 class AbstractPrint
,因此继承在这里很好。
另一方面,class AbstractRun
不是 AbstractPrint
,也不是AbstractAccess
。 AbstractRun
简单地处理/组合 AbstractPrint
和 AbstractAccess
。这种关系应该用聚合(或组合)来抽象,因为 AbstractRun
has a reference/pointer to a AbstractRun
and a AbstractPrint
.这将使 AbstractRun
具体化,所以让我们将其重命名为 Runner
.
class Runner
{
public:
// We now need a constructor to set the references.
Runner(AbstractAccess& access, AbstractPrint& print) :
accessor(access), printer(print) {}
void run (void) {
printer.print(accessor.access());
}
private:
AbstractAccess& accessor; // has a AbstractAccess
AbstractPrint& printer; // has a AbstractPrint
};
现在 Access
和 Print
可以像以前一样定义了。
但让我们也改进它们:
class Print: public virtual AbstractPrint {
public:
void print (string s) {
cout << s << endl;
}
};
我们不需要虚拟继承。虚拟继承用于解决钻石问题。但是没有钻石比 AbstractRunner 更具体 class。因此,让我们删除不必要的限定符。
class Accessor : public AbstractAccess {
public:
string access (void){
return name;
}
void setName(string name) {
this->name = name;
}
private:
string name;
};
class Print: public AbstractPrint {
public:
void print (string s) {
cout << s << endl;
}
};
此外,如果您有兼容 C++11 的编译器,我建议您为覆盖基函数的方法添加 override
限定符,以便能够区分从中获取的方法base class 而不是.
class Accessor : public AbstractAccess {
public:
string access (void) override { //overrides AbstractAcces method
return name;
}
void setName(string name) { //does not override. is a method at Accessor level
this->name = name;
}
private:
string name;
};
现在初始化一个Runner
时,我们需要传递具体的访问器和打印机。可以这样做:
// Somewhere in a .cpp - file
Accessor accessor;
Print printer;
Runner runner(accessor, printe);
runner.run(); //will call printer and accessor through the references.
我有两个 'interface' classes:AbstractAccess
和 AbstractPrint
,以及 AbstractRun
class 继承自它们并使用它们的方法.
另外,我有两个接口实现:AbstractAccess
的访问器和 AbstractPrint
#include <iostream>
using namespace std;
class AbstractAccess {
public:
virtual string access (void) = 0;
};
class AbstractPrint {
public:
virtual void print (string) = 0;
};
class AbstractRun : virtual public AbstractAccess, virtual public AbstractPrint {
public:
void run (void) {
print(access());
}
};
class Accessor : virtual public AbstractAccess {
public:
string access (void){
return name;
}
void setName(string name) {
this->name = name;
}
private:
string name;
};
class Print: public virtual AbstractPrint {
public:
void print (string s) {
cout << s << endl;
}
};
是否有任何方法可以将 AbstractRun
中的接口转换为它们的实现或创建仅使用抽象运行 的 [=23] 的实现 class 运行 =] 方法但具有已实现的接口?
虽然你的问题已经解决了,但我进一步研究了这个问题,我想澄清一些关于继承的困惑。
当您的一个 class 与另一个 class 具有 "is a" 关系时,将使用继承。派生的 class 应该替代您继承自的 class。
在你的例子中,你可以安全地说 class Print
是一个 class AbstractPrint
并且 class Access
同样是一个 class AbstractPrint
,因此继承在这里很好。
另一方面,class AbstractRun
不是 AbstractPrint
,也不是AbstractAccess
。 AbstractRun
简单地处理/组合 AbstractPrint
和 AbstractAccess
。这种关系应该用聚合(或组合)来抽象,因为 AbstractRun
has a reference/pointer to a AbstractRun
and a AbstractPrint
.这将使 AbstractRun
具体化,所以让我们将其重命名为 Runner
.
class Runner
{
public:
// We now need a constructor to set the references.
Runner(AbstractAccess& access, AbstractPrint& print) :
accessor(access), printer(print) {}
void run (void) {
printer.print(accessor.access());
}
private:
AbstractAccess& accessor; // has a AbstractAccess
AbstractPrint& printer; // has a AbstractPrint
};
现在 Access
和 Print
可以像以前一样定义了。
但让我们也改进它们:
class Print: public virtual AbstractPrint {
public:
void print (string s) {
cout << s << endl;
}
};
我们不需要虚拟继承。虚拟继承用于解决钻石问题。但是没有钻石比 AbstractRunner 更具体 class。因此,让我们删除不必要的限定符。
class Accessor : public AbstractAccess {
public:
string access (void){
return name;
}
void setName(string name) {
this->name = name;
}
private:
string name;
};
class Print: public AbstractPrint {
public:
void print (string s) {
cout << s << endl;
}
};
此外,如果您有兼容 C++11 的编译器,我建议您为覆盖基函数的方法添加 override
限定符,以便能够区分从中获取的方法base class 而不是.
class Accessor : public AbstractAccess {
public:
string access (void) override { //overrides AbstractAcces method
return name;
}
void setName(string name) { //does not override. is a method at Accessor level
this->name = name;
}
private:
string name;
};
现在初始化一个Runner
时,我们需要传递具体的访问器和打印机。可以这样做:
// Somewhere in a .cpp - file
Accessor accessor;
Print printer;
Runner runner(accessor, printe);
runner.run(); //will call printer and accessor through the references.