我在一篇文章中发现"static_cast用于非多态类型转换,而dynamic_cast用于多态类型转换".我知道int和double不是多态类型.
但是,我还发现static_cast可以在基类和派生类之间使用.这里的多态类型是什么意思?有人说多态类型意味着具有虚函数的基类.是对的吗?这是唯一的情况吗?还有什么?任何人都可以为我详细说明这个吗?
小智 17
首先,这篇文章并不完全正确. dynamic_cast检查对象的类型并且可能会失败,static_cast不会检查并且很大程度上要求程序员知道他们正在做什么(尽管它会针对某些严重的错误发出编译错误),但它们都可能在多态情况下使用.(dynamic_cast还有一个附加要求,即至少有一个涉及的类型有一个虚方法.)
简而言之,C++中的多态性是通过单独定义的接口使用对象.该接口是基类,当它具有虚拟方法时,它几乎总是有用.
然而,在没有任何虚拟方法的情况下拥有多态性是罕见但可能的; 通常这是一个糟糕的设计或不得不满足外部要求的标志,因此,没有办法给出一个适合这里的好例子.("当你看到它时,你会知道什么时候使用它",不幸的是,这是我能给你的最佳建议.)
多态性例子:
struct Animal {
virtual ~Animal() {}
virtual void speak() = 0;
};
struct Cat : Animal {
virtual void speak() { std::cout << "meow\n"; }
};
struct Dog : Animal {
virtual void speak() { std::cout << "wouf\n"; }
};
struct Programmer : Animal {
virtual void speak() {
std::clog << "I refuse to participate in this trite example.\n";
}
};
Run Code Online (Sandbox Code Playgroud)
稍微练习上面的类 - 也看我的通用工厂示例:
std::auto_ptr<Animal> new_animal(std::string const& name) {
if (name == "cat") return std::auto_ptr<Animal>(new Cat());
if (name == "dog") return std::auto_ptr<Animal>(new Dog());
if (name == "human") return std::auto_ptr<Animal>(new Programmer());
throw std::logic_error("unknown animal type");
}
int main(int argc, char** argv) try {
std::auto_ptr<Animal> p = new_animal(argc > 1 ? argv[1] : "human");
p->speak();
return 0;
}
catch (std::exception& e) {
std::clog << "error: " << e.what() << std::endl;
return 1;
}
Run Code Online (Sandbox Code Playgroud)
它也可以在没有继承的情况下使用多态,因为它实际上是一种设计技术或风格.(我拒绝在这里使用流行语模式 ......:P)
Pra*_*rav 14
static_cast可以在指向相关类的指针之间执行转换,不仅可以从派生类到其基类,还可以从基类到其派生类.这确保了如果转换了适当的对象,至少类是兼容的,但是在运行时期间不执行安全检查以检查被转换的对象实际上是否是目标类型的完整对象.因此,程序员应确保转换是安全的.另一方面,避免了dynamic_cast的类型安全检查的开销.
static_cast也可用于执行任何其他非指针转换,也可以隐式执行,例如基本类型之间的标准转换:
double d=3.14159265;
int i = static_cast<int>(d);
Run Code Online (Sandbox Code Playgroud)
dynamic_cast只能用于指针和对象的引用.其目的是确保类型转换的结果是所请求类的有效完整对象.
因此,当我们将类转换为其基类之一时,dynamic_cast 总是成功的.
// dynamic_cast
#include <iostream>
#include <exception>
using namespace std;
class CBase { virtual void dummy() {} };
class CDerived: public CBase { int a; };
int main () {
try {
CBase * pba = new CDerived;
CBase * pbb = new CBase;
CDerived * pd;
pd = dynamic_cast<CDerived*>(pba);
if (pd==0) cout << "Null pointer on first type-cast" << endl;
pd = dynamic_cast<CDerived*>(pbb);
if (pd==0) cout << "Null pointer on second type-cast" << endl;
} catch (exception& e) {cout << "Exception: " << e.what();}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
兼容性说明:dynamic_cast需要运行时类型信息(RTTI)来跟踪动态类型.某些编译器支持此功能作为默认禁用的选项.必须为运行时类型检查启用此选项,以使用dynamic_cast正常工作.
虚函数负责C++中的运行时多态性.具有至少一个虚函数的类具有多态类型.
也读这个.已经清楚地写到了这一点A class that declares or inherits a virtual function is called a polymorphic class.
嗯,答案很简单.具有至少一个虚函数的类称为多态类型.这也可能只是一个析构函数.
所以以下是' 多态类型'.
struct Test {
virtual ~Test();
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15838 次 |
| 最近记录: |