什么是c++中的多态类型?

时间:2021-01-09 21:38:06

I found in one article saying "static_cast is used for non-polymorphic type casting and dynamic_cast is used for polymorphic type casting". I understand that int and double are not polymorphic types.

我在一篇文章中发现,“static_cast用于非多态类型的浇注,而dynamic_cast用于多态类型转换”。我知道int和double不是多态类型。

However, I also found that static_cast can be used between base class and derived class. What does polymorphic type here mean? Some people says polymorphic type means the base class with virtual function. Is that right? Is this the only situation? What else? Can anybody could elaborate this for me more?

但是,我还发现,static_cast可以在基类和派生类之间使用。多态性在这里意味着什么?有些人说多态类型是指具有虚函数的基类。是这样吗?这是唯一的情况吗?还有什么?有人能详细解释一下吗?

5 个解决方案

#1


15  

First of all, the article is not completely correct. dynamic_cast checks the type of an object and may fail, static_cast does not check and largely requires the programmer to know what they're doing (though it will issue compile errors for some egregious mistakes), but they may both be used in polymorphic situations. (dynamic_cast has the additional requirement that at least one of the involved types has a virtual method.)

首先,这篇文章不完全正确。dynamic_cast检查对象的类型,可能会失败,static_cast不检查,并且很大程度上要求程序员知道他们在做什么(尽管它会为一些错误的错误发出编译错误),但是它们都可以在多态环境中使用。(dynamic_cast有一个额外的要求,至少其中一个涉及的类型有一个虚拟方法。)

Polymorphism in C++, in a nutshell, is using objects through a separately-defined interface. That interface is the base class, and it is almost always only useful to do this when it has virtual methods.

简单地说,c++中的多态性是通过一个单独定义的接口来使用对象。该接口是基类,当它有虚拟方法时,它几乎总是只会有用。

However, it's rare-but-possible to have polymorphism without any virtual methods; often this is a sign of either bad design or having to meet external requirements, and because of that, there's no way to give a good example that will fit here. ("You'll know when to use it when you see it," is, unfortunately, the best advice I can give you here.)

然而,在没有虚拟方法的情况下,具有多态性是可能的;通常情况下,这是糟糕的设计或者必须满足外部需求的标志,因此,没有办法给出一个合适的例子。(“当你看到它时,你会知道什么时候该用它。”不幸的是,这是我能给你的最好建议。)

Polymorphism example:

多态性的例子:

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";
  }
};

Exercising the above classes slightly—also see my generic factory example:

同时,我也看到了我的通用工厂例子:

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;
}

It's also possible to use polymorphism without inheritance, as it's really a design technique or style. (I refuse to use the buzzword pattern here... :P)

还可以使用无继承的多态性,因为它实际上是一种设计技术或样式。(我拒绝使用这里的流行词模式……):P)

#2


13  

static_cast can perform conversions between pointers to related classes, not only from the derived class to its base, but also from a base class to its derived. This ensures that at least the classes are compatible if the proper object is converted, but no safety check is performed during runtime to check if the object being converted is in fact a full object of the destination type. Therefore, it is up to the programmer to ensure that the conversion is safe. On the other side, the overhead of the type-safety checks of dynamic_cast is avoided.

static_cast可以在指向相关类的指针之间执行转换,不仅从派生类到其基础,还可以从基类到派生类。这确保了如果正确的对象被转换,至少类是兼容的,但是在运行时不执行安全检查来检查被转换的对象是否实际上是目标类型的完整对象。因此,由程序员来确保转换是安全的。另一方面,避免了对dynamic_cast进行类型安全检查的开销。

static_cast can also be used to perform any other non-pointer conversion that could also be performed implicitly, like for example standard conversion between fundamental types:

static_cast还可以用于执行任何其他可以隐式执行的非指针转换,比如基本类型之间的标准转换:

double d=3.14159265;
int i = static_cast<int>(d); 

dynamic_cast can be used only with pointers and references to objects. Its purpose is to ensure that the result of the type conversion is a valid complete object of the requested class.

dynamic_cast只能用于指向对象的指针和引用。它的目的是确保类型转换的结果是请求类的有效完整对象。

Therefore, dynamic_cast is always successful when we cast a class to one of its base classes.

因此,当我们将一个类转换为它的一个基类时,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;
 }

Compatibility note: dynamic_cast requires the Run-Time Type Information (RTTI) to keep track of dynamic types . Some compilers support this feature as an option which is disabled by default. This must be enabled for runtime type checking using dynamic_cast to work properly.

兼容性注意:dynamic_cast需要运行时类型信息(RTTI)来跟踪动态类型。一些编译器支持这个特性,作为默认禁用的选项。这必须在运行时类型检查中启用,使用dynamic_cast来正常工作。

Virtual Functions are responsible for Run-time Polymorphism in C++. A class that has at least one virtual function has polymorphic type.

在c++中,虚函数负责运行时多态性。一个具有至少一个虚函数的类具有多态类型。

Read More....

阅读更多....

Read this too. It has been clearly written thatA class that declares or inherits a virtual function is called a polymorphic class.

读这篇文章。它已经被清楚地写出来,它声明或继承一个虚拟函数被称为多态类。

#3


7  

Well, the answer is simple. A class having atleast one virtual function is called a polymorphic type. This can be only a destructor also.

答案很简单。具有至少一个虚拟函数的类称为多态类型。这也只能是一个析构函数。

So the following is a 'polymorphic type'.

因此,下面是一个“多态类型”。

struct Test {
  virtual ~Test();
};

#4


2  

I think the full phrase is "polymorphic type casting". You are right that static_cast works on types that are not related by inheritance (double - int, etc) and the others answers point out how the casts work.

我认为完整的短语是“多态型铸造”。您是正确的,static_cast对与继承无关的类型(double - int等)进行工作,而其他的回答则指出了强制转换是如何工作的。

I don't think the statement implied the existence of a mythical polymorphic type though - just that static_cast also works on unrelated types. The statement was a little confusing though and it's good to clarify.

我不认为这句话暗示了一个神秘的多态性类型的存在——仅仅是static_cast也适用于不相关的类型。这个声明有点让人困惑,很好澄清。

#5


-1  

I think that we always define/declare the destructor of any class as virtual especially in an inheritance tree. Then we can say that almost all classes in an inheritance tree are polymorphic.

我认为我们总是定义/声明任何类的析构函数,特别是在继承树中。然后我们可以说,继承树中的几乎所有类都是多态的。

#1


15  

First of all, the article is not completely correct. dynamic_cast checks the type of an object and may fail, static_cast does not check and largely requires the programmer to know what they're doing (though it will issue compile errors for some egregious mistakes), but they may both be used in polymorphic situations. (dynamic_cast has the additional requirement that at least one of the involved types has a virtual method.)

首先,这篇文章不完全正确。dynamic_cast检查对象的类型,可能会失败,static_cast不检查,并且很大程度上要求程序员知道他们在做什么(尽管它会为一些错误的错误发出编译错误),但是它们都可以在多态环境中使用。(dynamic_cast有一个额外的要求,至少其中一个涉及的类型有一个虚拟方法。)

Polymorphism in C++, in a nutshell, is using objects through a separately-defined interface. That interface is the base class, and it is almost always only useful to do this when it has virtual methods.

简单地说,c++中的多态性是通过一个单独定义的接口来使用对象。该接口是基类,当它有虚拟方法时,它几乎总是只会有用。

However, it's rare-but-possible to have polymorphism without any virtual methods; often this is a sign of either bad design or having to meet external requirements, and because of that, there's no way to give a good example that will fit here. ("You'll know when to use it when you see it," is, unfortunately, the best advice I can give you here.)

然而,在没有虚拟方法的情况下,具有多态性是可能的;通常情况下,这是糟糕的设计或者必须满足外部需求的标志,因此,没有办法给出一个合适的例子。(“当你看到它时,你会知道什么时候该用它。”不幸的是,这是我能给你的最好建议。)

Polymorphism example:

多态性的例子:

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";
  }
};

Exercising the above classes slightly—also see my generic factory example:

同时,我也看到了我的通用工厂例子:

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;
}

It's also possible to use polymorphism without inheritance, as it's really a design technique or style. (I refuse to use the buzzword pattern here... :P)

还可以使用无继承的多态性,因为它实际上是一种设计技术或样式。(我拒绝使用这里的流行词模式……):P)

#2


13  

static_cast can perform conversions between pointers to related classes, not only from the derived class to its base, but also from a base class to its derived. This ensures that at least the classes are compatible if the proper object is converted, but no safety check is performed during runtime to check if the object being converted is in fact a full object of the destination type. Therefore, it is up to the programmer to ensure that the conversion is safe. On the other side, the overhead of the type-safety checks of dynamic_cast is avoided.

static_cast可以在指向相关类的指针之间执行转换,不仅从派生类到其基础,还可以从基类到派生类。这确保了如果正确的对象被转换,至少类是兼容的,但是在运行时不执行安全检查来检查被转换的对象是否实际上是目标类型的完整对象。因此,由程序员来确保转换是安全的。另一方面,避免了对dynamic_cast进行类型安全检查的开销。

static_cast can also be used to perform any other non-pointer conversion that could also be performed implicitly, like for example standard conversion between fundamental types:

static_cast还可以用于执行任何其他可以隐式执行的非指针转换,比如基本类型之间的标准转换:

double d=3.14159265;
int i = static_cast<int>(d); 

dynamic_cast can be used only with pointers and references to objects. Its purpose is to ensure that the result of the type conversion is a valid complete object of the requested class.

dynamic_cast只能用于指向对象的指针和引用。它的目的是确保类型转换的结果是请求类的有效完整对象。

Therefore, dynamic_cast is always successful when we cast a class to one of its base classes.

因此,当我们将一个类转换为它的一个基类时,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;
 }

Compatibility note: dynamic_cast requires the Run-Time Type Information (RTTI) to keep track of dynamic types . Some compilers support this feature as an option which is disabled by default. This must be enabled for runtime type checking using dynamic_cast to work properly.

兼容性注意:dynamic_cast需要运行时类型信息(RTTI)来跟踪动态类型。一些编译器支持这个特性,作为默认禁用的选项。这必须在运行时类型检查中启用,使用dynamic_cast来正常工作。

Virtual Functions are responsible for Run-time Polymorphism in C++. A class that has at least one virtual function has polymorphic type.

在c++中,虚函数负责运行时多态性。一个具有至少一个虚函数的类具有多态类型。

Read More....

阅读更多....

Read this too. It has been clearly written thatA class that declares or inherits a virtual function is called a polymorphic class.

读这篇文章。它已经被清楚地写出来,它声明或继承一个虚拟函数被称为多态类。

#3


7  

Well, the answer is simple. A class having atleast one virtual function is called a polymorphic type. This can be only a destructor also.

答案很简单。具有至少一个虚拟函数的类称为多态类型。这也只能是一个析构函数。

So the following is a 'polymorphic type'.

因此,下面是一个“多态类型”。

struct Test {
  virtual ~Test();
};

#4


2  

I think the full phrase is "polymorphic type casting". You are right that static_cast works on types that are not related by inheritance (double - int, etc) and the others answers point out how the casts work.

我认为完整的短语是“多态型铸造”。您是正确的,static_cast对与继承无关的类型(double - int等)进行工作,而其他的回答则指出了强制转换是如何工作的。

I don't think the statement implied the existence of a mythical polymorphic type though - just that static_cast also works on unrelated types. The statement was a little confusing though and it's good to clarify.

我不认为这句话暗示了一个神秘的多态性类型的存在——仅仅是static_cast也适用于不相关的类型。这个声明有点让人困惑,很好澄清。

#5


-1  

I think that we always define/declare the destructor of any class as virtual especially in an inheritance tree. Then we can say that almost all classes in an inheritance tree are polymorphic.

我认为我们总是定义/声明任何类的析构函数,特别是在继承树中。然后我们可以说,继承树中的几乎所有类都是多态的。