C ++转换是否创建一个新对象? [英] C++ Does casting create a new object?

查看:138
本文介绍了C ++转换是否创建一个新对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如上面的标题所示,我的问题只是一个C ++转换是否创建一个新的目标类的对象。当然,在使用Google,MSDN,IBM和stackoverflow的搜索工具之前,我已经提出了这个问题,但是我找不到合适的答案。



通过使用虚拟继承来解决钻石问题的实现:

  #include< iostream> 
#include< cstdlib>

struct A
{
int a;

A():a(2){}
};

struct B:virtual public A
{
int b;

B():b(7){}
};

struct C:virtual public A
{
int c;

C():c(1){}
};

struct END:virtual public B,virtual public C
{
int end;

END():end(8){}
};

int main()
{
END * end = new END()
A * a = dynamic_cast< A *>(end);
B * b = dynamic_cast< B *>(end);
C * c = dynamic_cast< C *>(end);

std :: cout<< 值a:\\\
a-> a:< a - > a<< \\\
\\\
;
std :: cout<< values of b:\\\
b-> a:< b - > a<< \\\
b-> b:< b - > b<< \\\
\\\
;
std :: cout<< c:\\\
c-> a:<< c - > a<< \\\
c-> c:< c - > c< \\\
\\\
;

std :: cout<< 结束的句柄:<端<< \\\
;
std :: cout<< Handle of a:<< a<< \\\
;
std :: cout<< Handle of b:<< b<< \\\
;
std :: cout<< Handle of c:<< c < \\\
\\\
;
system(PAUSE);
return 0;
}

据我所知,B和C的实际结构A的嵌入实例和B的变量。 C被破坏,因为B和C的虚拟A被合并到END中的一个嵌入对象以避免歧义。因为(我一直认为)dynamic_cast通常只增加指针存储的地址与嵌入(cast)目标类的偏移量,因为目标(B或C)类被划分为几个



但是如果我使用MSVC ++ 2011 Express运行示例,一切都会按预期发生(即它将运行,所有* .a输出2),指针只是稍微不同。因此,我怀疑,但是cast只是通过B的/ C的实例的内部偏移来移动源指针的地址。



但是怎么样呢?如何生成的B / C实例知道共享A对象的位置。因为在END对象中只有一个A对象,但通常是B和C中的A对象,B或C不能有A的实例,但实际上它们都有一个实例。



或者 virtual 只将对A的成员的调用委托给中央A对象,而不删除继承的每个基类的相应A对象virtual from A(即, virtual 实际上不会销毁继承的内部结构,因此不会使用它们的virtualized(= shared)成员)?



或者 virtual 创建一个新的偏移映射(即映射,它告诉所有成员相对于指针的地址偏移一个类实例,我dunno的实际术语)为这样的casted对象来处理他们的分布式?



我希望我澄清了一切,
BlueBlobb



PS:

对不起,如果有一些语法错误,我只是一个啤酒爱巴法力亚,不是母语:P



编辑

如果已添加这些行以输出所有int a的地址:

  std :: cout< Handle of end.a:< & end-> a<< \\\
;
std :: cout<< Handle of a.a:<< & a-> a<< \\\
;
std :: cout<< Handle of a.b:<< & b-> a<< \\\
;
std :: cout<< Handle of a.c:< & c-> a<< \\\
\\\
;

它们是一样的意味着只有一个A对象。

$ b $我的问题只是一个C ++转换是否创建一个新的目标类的对象。

$

b $ b

是,类类型的转换将创建该类型的新临时对象。



请注意,您的示例不会转换为任何地方的类:它执行的唯一转型是指针类型。这些转换确实创建了指针的新实例 - 但不是指向的对象。我不知道你的例子应该演示,也不知道它与你的问题有什么关系。



此外, dynamic_cast 是不必要的,你使用它;


由于(我一直认为)dynamic_cast通常只会增加指针存储的地址偏移嵌入的(演员的)目标类


您必须考虑 static_cast 或某事。 dynamic_cast 更强大。例如,它可以从 B * 转换为 C * ,即使它们在编译时不相关,到 END * ,然后备份另一个分支。 dynamic_cast 利用运行时类型信息。


/ C知道共享A对象的位置。


这是实现相关的。典型的实现将保留在派生类实例内的空间以存储对其虚拟基类实例的偏移。最导出类的构造函数初始化所有这些偏移。


As indicated in the title above, my question is simply whether or not a C++ cast does create a new object of the target class. Of course, I have used Google, MSDN, IBM and stackoverflow's search tool before asking this but I can't find an appropriate answer to my question.

Lets consider the following implementation of the diamond problem solved by using virtual inheritance:

#include <iostream>
#include <cstdlib>

struct A
{
  int a;

  A(): a(2) {  }
};

struct B: virtual public A
{
  int b;

  B(): b(7) {  }
};

struct C: virtual public A
{
  int c;

  C(): c(1) {  }
};

struct END: virtual public B, virtual public C
{
  int end;

  END(): end(8) {  }
};

int main()
{
  END *end = new END();
  A *a = dynamic_cast<A*>(end);
  B *b = dynamic_cast<B*>(end);
  C *c = dynamic_cast<C*>(end);

  std::cout << "Values of a:\na->a: " << a->a << "\n\n";
  std::cout << "Values of b:\nb->a: " << b->a << "\nb->b: " << b->b << "\n\n";
  std::cout << "Values of c:\nc->a: " << c->a << "\nc->c: " << c->c << "\n\n";

  std::cout << "Handle of end: " << end << "\n";
  std::cout << "Handle of a: " << a << "\n";
  std::cout << "Handle of b: " << b << "\n";
  std::cout << "Handle of c: " << c << "\n\n";
  system("PAUSE");
  return 0;
}

As I understood, the actual structure of B and C, which normally consists of both an embedded instance of A and variables of B resp. C, is destroyed since the virtual A of B and C is merged to one embedded object in END to avoid ambiguities. Since (as I always thought) dynamic_cast usually only increases the address stored by a pointer by the offset of the embedded (cast's) target class there will be a problem due to the fact that the target (B or C) class is divided into several parts.

But if I run the example with MSVC++ 2011 Express everything will happen as expected (i.e. it will run, all *.a output 2), the pointers only slightly differ. Therefor, I suspect that the casts nevertheless only move the addresses of the source pointers by the internal offset of B's / C's instance.

But how? How does the resulting instance of B / C know the position of the shared A object. Since there is only one A object inside the END object but normally an A object in B and C, either B or C must not have an instance of A, but, indeed, both seem to have an instance of it.

Or does virtual only delegate calls to A's members to a central A object without deleting the respective A objects of each base class which inherits virtual from A (i.e. does virtual actually not destroy the internal structure of inherited and therefor embedded objects but only not using their virtualized (= shared) members)?

Or does virtual create a new "offset map" (i.e. the map which tells the address offsets of all members relative to the pointer to a class instance, I dunno the actual term) for such casted objects to handle their "distributedness"?

I hope I have clarified everything, many thanks in advance
BlueBlobb

PS:
I'm sorry if there are some grammar mistakes, I'm only a beer loving Bavarian, not a native speaker :P

Edit:
If have added these lines to output the addresses of all int a's:

  std::cout << "Handle of end.a: " << &end->a << "\n";
  std::cout << "Handle of a.a: " << &a->a << "\n";
  std::cout << "Handle of a.b: " << &b->a << "\n";
  std::cout << "Handle of a.c: " << &c->a << "\n\n";

They are the same implying that there is indeed only one A object.

解决方案

my question is simply whether or not a C++ cast does create a new object of the target class.

Yes, a cast to a class type would create new temporary object of that type.

Note that your example doesn't cast to a class anywhere: the only casts it performs are to pointer types. Those casts do create new instances of pointers - but not of the objects pointed to. I'm not sure what your example was supposed to demonstrate, nor how it is related to your stated question.

Also, dynamic_cast is unnecessary where you use it; an implicit conversion would work just as well.

Since (as I always thought) dynamic_cast usually only increases the address stored by a pointer by the offset of the embedded (cast's) target class

You must be thinking of static_cast or something. dynamic_cast is much more powerful. For example, it can cast from B* to C*, even though they are unrelated at compile time, by going down to END* and then back up the other branch. dynamic_cast utilizes run-time type information.

How does the resulting instance of B / C know the position of the shared A object.

This is implementation-dependent. A typical implementation would reserve space within the derived class instance to store an offset to its virtual base class instance. The constructor of the most-derived class initializes all those offsets.

这篇关于C ++转换是否创建一个新对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆