有一个C++变量,可以是类FO或类条

有一个C++变量,可以是类FO或类条,c++,c++11,C++,C++11,我有兴趣写一个打印机输出两种不同的格式。让我们称它们为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("t

我有兴趣写一个打印机输出两种不同的格式。让我们称它们为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();
}
class Printer {
public:
  virtual ~Printer() = default;
  virtual void header() = 0;
};
class CSV : public Printer { 
  ...
};

class TXT : public Printer {
  ...
};
但是,由于您正在从丢失的删除中泄漏内存,因此我将在这里使用智能指针,而不是原始指针和新指针

#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();
}
您还应该从基类公开继承

int decider(int type) {
  Printer* prt;
  if (type == 1) {
     prt = new CSV;
  } else {
     prt = new TXT;
  }
  prt->header();
}
class Printer {
public:
  virtual ~Printer() = default;
  virtual void header() = 0;
};
class CSV : public Printer { 
  ...
};

class TXT : public Printer {
  ...
};
这是正确的方法:

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

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

我的意思是

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

   delete prt;
 }
您可以按如下方式调用

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

正如Daniel H所指出的,谢谢!这只有在您知道编译时的类型时才有效;如果CSV或TXT类型是在运行时确定的,则此解决方案是不可行的。

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

包括 类打印机{ 公众: 虚空头{}; }; 类别:公共打印机{ 公众: 无效标头{printfcsv\n;} }; 类别TXT:公用打印机{ 公众: 无效标头{printftxt\n;} }; 整数判定型{ 打印机*prt; 如果类型==1{ prt=新的CSV; }否则{ prt=新文本; } prt->header; } int main{ int型=1; 决策类型; 类型=0; 决策类型; }
在这段代码中不能说prt.header。将prt更改为prt_p,然后在if语句后制作一个打印机&prt,或者将最后一行更改为prt->header。多亏了你们两位。我相信打印机需要一个虚拟析构函数来避免UB。auto需要初始化类型推断。设计模式称为factory methodOperator new,返回指针。每个对new的调用都必须有一个匹配的调用才能删除!!为了使它能够正确工作而不泄漏或未定义的行为,您将需要一个在打印机中。它决定编译时不是运行时。@ DanielH -好点。我相信打印机需要一个虚拟析构函数来避免UB。扩展:考虑返回UnQuyJPTR而不是调用头函数。这将允许您在将来为类似的任务重用decider。还考虑使用枚举类型而不是int。