【发布时间】:2021-05-17 23:35:47
【问题描述】:
我有一个带有零个或两个参数的类 Obj。
- 无参数
- 第一个 arg 始终是 std::string 名称。
- 第二个参数应该是三种不同的类类型。
我想要这样的:
class Sphere{
public:
int radius=1;
int a;
};
class Plane{
public:
int a=11;
int b=12;
int c=13;
};
class Light{
public:
int pos=555;
int a;
};
class Obj{
public:
std::string name;
Sphere s;
Light l;
Plane p;
int type;
bool defined;
//with no arguments
Obj(){
defined=false;
type=0;
}
//Type Sphere as second arg
Obj(std::string name,Sphere _s){
defined=true;
type=1;
s=_s;
}
//Or Type Light as second arg
Obj(std::string name,Light _l){
defined=true;
type=2;
l=_l;
}
//Or Type Plane as second arg
Obj(std::string name,Plane _p){
defined=true;
type=3;
p=_p;
}
};
意思应该是能够将几个不同类型的对象放在同一个数组中,只用一种方式输入。
以某种方式可能吗?任何建议将不胜感激。谢谢
编辑:
(C++11)
知道它可以编译已经是一个很好的开始。谢谢。
上面的例子只有在 Sphere、Plane、Light 类有 没有参数。
向 Sphere、Plane、Light 类添加相同的参数编号也会失败。如果 3 个类具有不同数量的参数,则相同。
#include <iostream>
class Sphere{
public:
int radius=1;
int a;
Sphere( int _a ){
a=_a;
}
};
class Plane{
public:
int a=11;
int b=12;
int c=13;
Plane( int _a ){
a=_a;
}
//Plane(int _a,int _b,int _c){
// a=_a;b=_b;c=_c;
//}
};
class Light{
public:
int pos=555;
int a;
Light(int _a){
a=_a;
}
};
class Obj{
public:
std::string name;
Sphere s;
Light l;
Plane p;
int type;
bool defined;
//with no arguments
Obj(){
defined=false;
type=0;
}
//Type Sphere as second arg
Obj(std::string _name,Sphere _s){
name=_name;
defined=true;
type=1;
s=_s;
}
//Or Type Light as second arg
Obj(std::string _name,Light _l){
name=_name;
defined=true;
type=2;
l=_l;
}
//Or Type Plane as second arg
Obj(std::string _name,Plane _p){
name = _name;
defined=true;
type=3;
p=_p;
}
};
using namespace std;
int main()
{
int a=111;
int b=222;
int c=333;
Obj sph1=Obj("sphere1",Sphere(a));
Obj sph2=Obj("sphere2",Sphere(b));
Obj lig1=Obj("Light1", Light(c));
Obj lig2=Obj("Light2", Light(c));
//Obj pla1=Obj("Plane1", Plane(a,b,c));
//Obj pla2=Obj("Plane2", Plane(c,b,a));
cout<<"sp1 name:" << sph1.name << endl;
cout<<"sp1 radius:"<< sph1.s.radius << endl;
//cout<<"pla1 name:" << pla1.name << endl;
//cout<<"pla1 p1:" << pla1.p.p1 << endl;
//cout<<"pla2 name:" << pla1.name << endl;
//cout<<"pla2 p1:" << pla1.p.p1 << endl;
cout<<"Hello"<<endl;
return 0;
}
这里是编译器错误:
Error:
vt.cpp: In constructor ‘Obj::Obj()’:
vt.cpp:64:10: error: no matching function for call to ‘Sphere::Sphere()’
Obj(){
^
vt.cpp:22:5: note: candidate: Sphere::Sphere(int)
Sphere( int _a ){
^~~~~~
vt.cpp:22:5: note: candidate expects 1 argument, 0 provided
vt.cpp:18:7: note: candidate: constexpr Sphere::Sphere(const Sphere&)
class Sphere{
^~~~~~
【问题讨论】:
-
如果一个“对象”只能是这三样东西之一,那么它存储所有三样东西的实例是没有意义的。看起来您正在尝试制作某种变体,但实际上您可能应该做的是使用多态性来创建
Sphere、Light和Plane对象,它们都是Obj的子类。 -
所有你做错的事情都被拼错了
std::string为std:string。一旦我解决了这个问题,代码就会编译并工作。它可能不是最有效的,但它确实有效。它不适合你吗? -
您也可以使用
std::variant<Sphere, Light, Plane>作为Obj的成员 -
你后面的错误是因为
Plane没有默认构造函数。 -
如果你不想依赖 C++17,你总是可以去“老派”并使用Factory pattern
标签: c++ class initializer