gpt4 book ai didi

C++ 接口(interface)、继承、多态性

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:21:23 26 4
gpt4 key购买 nike

想象一下这个场景:

  • 接口(interface)I1:m1(),由C1类实现
  • 接口(interface)I2:m2(),由C2类实现
  • 接口(interface)I3:m3(),由C3类实现

我想定义接受参数 arg 的函数。

void f1(I1 arg) {
use m1()
}

void f2([I1, I2] arg) {
use m1() and m2()
}

void f3([I2, I3] arg) {
use m2() and m3()
}

然后我要定义:

  • 一个“union ”接口(interface) I123,它具有所有方法,由 C123
  • 实现
  • 一个“union ”类C123,它继承现有类C1C2C3 的实现方法。

然后我想实例化C123并将其与f1f2f3一起使用。

C123 obj;

f1(obj);
f2(obj);
f3(obj);

问题

  1. 这在 C++ 中可行吗?
  2. 没有接口(interface)是否可行?例如。函数 f2 将采用 [C1, C2] 而不是 [I1, I2]

代码

#include <string>
#include <iostream>

using namespace std;

class C1 {
protected:
int i;
public:
int getI() const { return i; }
void setI(int i_) { i = i_; }
};

class C2 {
protected:
string s;
public:
string getS() const { return s; }
void setS(string s_) { s = s_; }
};

class C3 {
protected:
float f;
public:
float getF() const { return f; }
void setF(float f_) { f = f_; }
};

class C23 : public C2, public C3 {};
class C123 : public C1, public C2, public C3 {};

void f3(C23 arg) {
arg.setS(to_string(arg.getF()));
}


int main() {

C123 obj;

f3(obj);

std::cout << obj.getS();
}

错误信息

a.cc: In function ‘int main()’:
a.cc:42:9: error: could not convert ‘obj’ from ‘C123’ to ‘C23’
f3(obj);

最佳答案

  1. Is this possible in C++?

是的,可以用 C++ 实现。

Example solution using interfaces

#include <string>
#include <iostream>

using namespace std;

class I1 {
public:
virtual int getI() const = 0;
virtual void setI(int i) = 0;
};

class I2 {
public:
virtual string getS() const = 0;
virtual void setS(string s) = 0;
};

class I3 {
public:
virtual float getF() const = 0;
virtual void setF(float f) = 0;
};

class C1 : public I1 {
protected:
int i;
public:
int getI() const { return i; }
void setI(int i_) { i = i_; }
};

class C12 : public I1, public I2 {
protected:
int i;
string s;
public:
int getI() const { return i; }
void setI(int i_) { i = i_; }
string getS() const { return s; }
void setS(string s_) { s = s_; }
};

class C123 : public I1, public I2, public I3 {
protected:
int i;
string s;
float f;
public:
int getI() const { return i; }
void setI(int i_) { i = i_; }
string getS() const { return s; }
void setS(string s_) { s = s_; }
float getF() const { return f; }
void setF(float f_) { f = f_; }
};

template<class T>
void f1(const T& c1)
{
cout << "f1:\n";
cout << " getI: " << c1.getI() << endl;
}

template<class T>
void f2(const T& c12)
{
cout << "f2:\n";
cout << " getI: " << c12.getI() << endl;
cout << " getS: " << c12.getS() << endl;
}

template<class T>
void f3(const T& c23)
{
cout << "f3:\n";
cout << " getS: " << c23.getS() << endl;
cout << " getF: " << c23.getF() << endl;
}

void test()
{
C1 c1;
c1.setI(1);
f1(c1);

cout << "\n===== " << endl;

C12 c12;
c12.setI(12);
c12.setS("str12");
f1(c12);
f2(c12);

cout << "\n===== " << endl;

C123 c123;
c123.setI(123);
c123.setF(1.23f);
c123.setS("str123");
f1(c123);
f2(c123);
f3(c123);

cout << "\n===== " << endl;
}

int main()
{
test();
}
  1. Is it possible without interfaces? Eg. function f2 would take [C1, C2] instead of [I1, I2].

是的,没有接口(interface)也可以做到这一点。

Solution using virtual inheritance (without using interfaces) :

#include <string>
#include <iostream>

using namespace std;

class C1 {
protected:
int i;
public:
int getI() const { return i; }
void setI(int i_) { i = i_; }
};

class C2 {
protected:
string s;
public:
string getS() const { return s; }
void setS(string s_) { s = s_; }
};

class C3 {
protected:
float f;
public:
float getF() const { return f; }
void setF(float f_) { f = f_; }
};

class C12 : public virtual C1, public virtual C2
{
};

class C23 : public virtual C2, public virtual C3
{
};

class C123 : public virtual C1, public virtual C12, public virtual C23
{
};


void f1(const C1& c1)
{
cout << "f1:\n";
cout << " getI: " << c1.getI() << endl;
}

void f2(const C12& c12)
{
cout << "f2:\n";
cout << " getI: " << c12.getI() << endl;
cout << " getS: " << c12.getS() << endl;
}

void f3(const C23& c23)
{
cout << "f3:\n";
cout << " getS: " << c23.getS() << endl;
cout << " getF: " << c23.getF() << endl;
}

void test()
{
C1 c1;
c1.setI(1);
f1(c1);

cout << "\n===== " << endl;

C12 c12;
c12.setI(12);
c12.setS("str12");
f1(c12);
f2(c12);

cout << "\n===== " << endl;

C123 c123;
c123.setI(123);
c123.setF(1.23f);
c123.setS("str123");
f1(c123);
f2(c123);
f3(c123);

cout << "\n===== " << endl;
}

int main()
{
test();
}

一些解释。如果你需要你的 f2 只接受 C1 和 C2(没有 C3),那么它必须是在 C1 和 C2 上都继承的独立类型。 f3 也一样。然后,如果您遵循该逻辑并在不使用虚拟继承的情况下创建类 C12C23,那么您现在应该从 C12 和 C23 继承的 C123 最终将具有多个拷贝C2,当您调用 f2 和 f3 时,您会从 getS 获得不同的值。虚拟继承确保在继承层次结构中只有一个类的拷贝。

a "union" class C123 which inherits implemented methods from existing classes C1, C2, C3

Solution that use virtual inheritance and interfaces

#include <string>
#include <iostream>

using namespace std;

class I1 {
public:
virtual int getI() const = 0;
virtual void setI(int i) = 0;
};

class I2 {
public:
virtual string getS() const = 0;
virtual void setS(string s) = 0;
};

class I3 {
public:
virtual float getF() const = 0;
virtual void setF(float f) = 0;
};

class I12 : virtual public I1, virtual public I2 {};
class I23 : virtual public I2, virtual public I3 {};
class I123 : virtual public I12, virtual public I23 {};

class C1 : virtual public I1 {
protected:
int i;
public:
int getI() const { return i; }
void setI(int i_) { i = i_; }
};

class C2 : virtual public I2 {
protected:
string s;
public:
string getS() const { return s; }
void setS(string s_) { s = s_; }
};

class C3 : virtual public I3 {
protected:
float f;
public:
float getF() const { return f; }
void setF(float f_) { f = f_; }
};

class C12 : public I12, public C1, public C2 {};
class C123 : public I123, public C1, public C2, public C3 {};

void f1(const I1& c1)
{
cout << "f1:\n";
cout << " getI: " << c1.getI() << endl;
}

void f2(const I12& c12)
{
cout << "f2:\n";
cout << " getI: " << c12.getI() << endl;
cout << " getS: " << c12.getS() << endl;
}

void f3(const I123& c23)
{
cout << "f3:\n";
cout << " getS: " << c23.getS() << endl;
cout << " getF: " << c23.getF() << endl;
}

void test()
{
C1 c1;
c1.setI(1);
f1(c1);

cout << "\n===== " << endl;

C12 c12;
c12.setI(12);
c12.setS("str12");
f1(c12);
f2(c12);

cout << "\n===== " << endl;

C123 c123;
c123.setI(123);
c123.setF(1.23f);
c123.setS("str123");
f1(c123);
f2(c123);
f3(c123);

cout << "\n===== " << endl;
}

int main()
{
test();
}

所有解决方案都应产生此输出:

f1:
getI: 1

=====
f1:
getI: 12
f2:
getI: 12
getS: str12

=====
f1:
getI: 123
f2:
getI: 123
getS: str123
f3:
getS: str123
getF: 1.23

=====

关于C++ 接口(interface)、继承、多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43430511/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com