int main() {
if(i = 0) {
myclass1 a = "Example1";
}
else {
myclass2 a = "Example2";
}
cout << a << endl;
}
Run Code Online (Sandbox Code Playgroud)
我知道一种方法是通过在块外定义它,但如果a在检查条件之前我还没有确定什么类型,该i怎么办?
Aki*_*ira 27
如果你能够使用c ++ 17,你可以使用std::variant或者std::any你的类型没有公共基类.这些类是任何或指定类型的类型安全容器.一个例子std::variant可以是:
#include <iostream>
#include <string>
#include <variant>
int main() {
bool input = false;
std::cin >> input;
std::variant<int, long, double, std::string> myVariant;
if(input)
myVariant = "Example1";
else
myVariant = 3.14;
std::visit([](auto&& arg) { std::cout << arg << std::endl; }, myVariant);
}
Run Code Online (Sandbox Code Playgroud)
而不是c ++ 17你也可以使用boost::variant或者boost::any.
650*_*502 20
C++是一种静态类型语言,需要在编译时知道代码中使用的变量类型.
没有办法编写一个C++程序,其中std::cout << a;编译语句并且a直到运行时才知道类型.
为此,您需要一种动态类型语言,例如Python或JavaScript.
你可以尝试多态.假设myclass1并myclass2"实现"一个叫做的类myclass,你可以这样做:
int main() {
myclass*a;
if (i=0) {
a = new myclass1("Example1");
} else {
a = new myclass2("Example2");
}
cout<<*a<<endl;
}
Run Code Online (Sandbox Code Playgroud)
如果您想积极使用该类型myclass1或myclass2稍后,您可以使用dynamic_cast,但根据您的需要以及您在继承的类和基类中实现的行为,可能没有必要.
注意我在这里使用一个原始指针,因为它是一个短命的对象,很明显程序已经结束.我鼓励您阅读有关智能指针的信息,并适当使用它们以避免内存泄漏.注意某些平台中的内存泄漏一直持续到重启后,可能需要手动释放(删除)已分配的内存.更多关于一切在这里.
int main() {
auto call = [](auto a) {
std::cout << a << std::endl;
};
if(i = 0)
call(myclass1 { "Example1" });
else
call(myclass2 { "Example2" });
}
Run Code Online (Sandbox Code Playgroud)
这最终需要多态性,并且可选地,如果你想让它更优雅,那就是工厂模式.工厂模式并不神奇,它只是隐藏if在一个漂亮的包装内.
为什么不采用另一种方法,例如std::variant基本上是union伪装的?好吧,如果你能够存储不同类型的东西,甚至是同名的任何种类(std::any),这很好,但它不是很有用,因为你也想对这个对象做一些有意义的事情.如果你想做完全不同的,无关的事情,那么你也可以拥有if块的不同对象(并使用完全不同的代码).但是,如果要在不同对象上执行相同或类似的操作,则它们(通常)需要相同或相关类型.
不同类型通常不具有相同的数据成员或相同的可公开访问的成员函数.因此,在具有不同类型的源代码级别上执行相同的操作通常不起作用(除了巧合).
但是如果两个类在它们的接口上确实具有相同的子集,并且您希望能够以一种或另一种方式交替地进行,那么继承基类是最自然和惯用的事情.这就是多态性的发明.使用惯用的东西.
(您可以通过模板帮助程序获得在不同的,不相关的类型上调用具有相同名称的函数的相同净效果,并假设您使用的名称存在,这将起作用,但它不是那么好的样式,并且它通过两次实现该功能导致巨大膨胀).