Class 数据成员可以是两种类型之一
Class with data member that can be one of two types
可能最好用一些代码来解释:
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();
}
此工作流 "almost" 在使用增强变体或增强任何变体时有效,但我要避免的是对 getData3 的结果调用 boost::get 以获取实际类型。换句话说,我不希望 MyClass 的使用者必须知道 data3 中存储的是 A 还是 B。我只希望他们能够调用 getData3(),这是在创建时传递的任何类型。
我认为通过具有模板 specialization/recursive 继承的模板是可能的,但我不太清楚如何让它工作。也许它看起来像这样?
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();
}
但是这行不通,因为我们不能有非静态模板 class 成员。
要执行您正在尝试的操作,您需要将模板应用于整个 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();
}
你可以在这里使用 union 来设置你在创建时想要的数据类型以及你在检索时得到的数据类型。
Union 为其所有成员分配一个公共内存位置。一个union占用的内存会大到足以容纳union的最大成员。
union AorB
{
A;
B;
};
然后在上面的程序中使用
可能最好用一些代码来解释:
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();
}
此工作流 "almost" 在使用增强变体或增强任何变体时有效,但我要避免的是对 getData3 的结果调用 boost::get 以获取实际类型。换句话说,我不希望 MyClass 的使用者必须知道 data3 中存储的是 A 还是 B。我只希望他们能够调用 getData3(),这是在创建时传递的任何类型。
我认为通过具有模板 specialization/recursive 继承的模板是可能的,但我不太清楚如何让它工作。也许它看起来像这样?
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();
}
但是这行不通,因为我们不能有非静态模板 class 成员。
要执行您正在尝试的操作,您需要将模板应用于整个 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();
}
你可以在这里使用 union 来设置你在创建时想要的数据类型以及你在检索时得到的数据类型。 Union 为其所有成员分配一个公共内存位置。一个union占用的内存会大到足以容纳union的最大成员。
union AorB
{
A;
B;
};
然后在上面的程序中使用