简体   繁体   English

具有可以是两种类型之一的数据成员的类

[英]Class with data member that can be one of two types

Probably best explained with some code:可能最好用一些代码来解释:

class MyClass {
  public:
    MyClass(const std::string& d1, const std::string& d2, const std::vector<AorB>& d3) : data1(d1), data2(d2), data3(d3) {}

    std::string getData1();
    std::string getData2();
    std::vector<AorB> getData3();

  private:
    std::string data1;
    std::string data2;
    std::vector<AorB> data3;
}

int main() {
  MyClass myClassA("d1", "d2", std::vector<A>());
  MyClass myClassB("d1", "d2", std::vector<B>());

  A myA = myClassA.getData3();
  B myB = myClassB.getData3();
}

This workflow "almost" works when using boost variants or boost any, but the thing I'm trying to avoid is the call to boost::get on the result of getData3 to get the actual type.当使用 boost 变体或 boost any 时,此工作流程“几乎”有效,但我试图避免的是在 getData3 的结果上调用 boost::get 以获取实际类型。 In other words, I don't want the consumer of MyClass to have to know whether A or B is stored in data3.换句话说,我不希望 MyClass 的使用者必须知道 data3 中存储的是 A 还是 B。 I just want them to be able to call getData3() which is whatever type it was passed upon creation.我只是希望他们能够调用 getData3(),它是创建时传递的任何类型。

I think it's possible through templates with template specialization/recursive inheritence, but I can't quite figure out how to get that working.我认为通过具有模板专业化/递归继承的模板是可能的,但我不太清楚如何让它工作。 Maybe it will look something like this?也许它看起来像这样?

class MyClass {
  public:
    template <typename AorB>
    MyClass(const std::string& d1, const std::string& d2, const std::vector<AorB>& d3) : data1(d1), data2(d2), data3(d3) {}

    std::string getData1();
    std::string getData2();

    template <typename AorB>
    std::vector<AorB> getData3();

  private:
    std::string data1;
    std::string data2;

    template <typename AorB>
    std::vector<AorB> data3;
  }

  int main() {
    MyClass myClassA<A>("d1", "d2", std::vector<A>());
    MyClass myClassB<B>("d1", "d2", std::vector<B>());

    A myA = myClassA.getData3();
    B myB = myClassB.getData3();
  }

However this won't work because we can't have non-static template class members.但是这不起作用,因为我们不能有非静态模板类成员。

To do what you are attempting, you would need to apply the template to MyClass as a whole, eg:要执行您正在尝试的操作,您需要将模板整体应用于MyClass ,例如:

template <typename AorB>
class MyClass {
  public:
    MyClass(const std::string& d1, const std::string& d2, const std::vector<AorB>& d3) : data1(d1), data2(d2), data3(d3) {}

    std::string getData1();
    std::string getData2();
    std::vector<AorB> getData3();

  private:
    std::string data1;
    std::string data2;
    std::vector<AorB> data3;
};

int main() {
  MyClass<A> myClassA("d1", "d2", std::vector<A>());
  MyClass<B> myClassB("d1", "d2", std::vector<B>());

  A myA = myClassA.getData3();
  B myB = myClassB.getData3();
}

you can use union here to set the datatype whatever you want at the time of creation and that what you got at the time of retrieval.您可以在此处使用 union 来设置创建时所需的数据类型以及检索时获得的数据类型。 Union allocates a common memory location for all its members. Union 为其所有成员分配一个公共内存位置。 The memory occupied by a union will be large enough to hold the largest member of the union.一个联合所占用的内存将足够容纳该联合中最大的成员。

union AorB
   {
         A;
         B;
   };

Then use in above program然后在上面的程序中使用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM