微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有一个 C++ 变量可以是 Class Foo 或 Class Bar

如何解决有一个 C++ 变量可以是 Class Foo 或 Class Bar

我有兴趣编写一个打印机来输出两种不同的格式。我们称它们为 txt 和 csv。

可以在 C++ 中实现类似下面的内容吗?

class Printer {
public:
  virtual void header() = 0;
};

class CSV : Printer {
public:
 void header() { printf("csv\n"); }
};

class TXT : Printer {
public:
 void header() { printf("txt\n"); }
};

int decider(int type) {
  auto prt;
  if (type == 1) {
     prt = new CSV;
  } else {
     prt = new TXT;
  }
  prt.header();
}

如果不是,除了做类似的事情还有什么替代方法

解决方法

你需要一个指向基类的指针,而不是 auto

int decider(int type) {
  Printer* prt;
  if (type == 1) {
     prt = new CSV;
  } else {
     prt = new TXT;
  }
  prt->header();
}

但不是原始指针和 new(因为您正在从丢失的 delete 中泄漏内存)我会在这里使用智能指针

#include <memory>

int decider(int type) {
  std::unique_ptr<Printer> prt;
  if (type == 1) {
     prt = std::make_unique<CSV>();
  } else {
     prt = std::make_unique<TXT>();
  }
  prt->header();
}

正如@FredLarson 所指出的,您的基类中还需要一个虚拟析构函数

class Printer {
public:
  virtual ~Printer() = default;
  virtual void header() = 0;
};

你也应该从基类公开继承

class CSV : public Printer { 
  ...
};

class TXT : public Printer {
  ...
};
,

这是正确的方法:

In [1966]: df1 = pd.DataFrame(Vitals_data)

In [1967]: df2 = pd.DataFrame(Vitals_date)

In [1975]: df = pd.concat([df1,df2.rename(columns={'BMI':'Date'})['Date']],1)

In [1976]: df
Out[1976]: 
  BMI   BP BloodSugar ThyroidFunction        Date
0  40  123        130               3  16-04-2021
1  41  110        120               3  17-04-2021
,

是的,这种多态性是可能的。 这是一个基于您的可运行示例:

#include <stdio.h>

class Printer {
public:
  virtual void header() {};
};

class CSV : public Printer {
public:
 void header() { printf("csv\n"); }
};

class TXT : public Printer {
public:
 void header() { printf("txt\n"); }
};

int decider(int type) {
  Printer* prt;
  if (type == 1) {
     prt = new CSV();
  } else {
     prt = new TXT();
  }
  prt->header();
}

int main() {

    int type = 1;

    decider(type);

    type = 0;

    decider(type);
}
,

将所需类型作为模板参数传递怎么样?

我的意思是

template <typename T>
void decider ()
 {
   auto prt = new T;
   prt.header();

   delete prt;
 }

您可以按如下方式调用

decider<CSV>();
decider<TXT>();

正如 Daniel H 所指出的(谢谢!)这仅在您知道编译时类型时才有效;如果类型(CSVTXT)是在运行时决定的,则此解决方案是不切实际的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。