关于 c++的 using 声明与析构函数调用问题

2015-07-16 14:12:51 +08:00
 linux40
http://www.zhihu.com/question/32233786
是否与继承有关,为什么using声明了一下string就行呢?
https://gist.github.com/anonymous/a8faec72cb1423261c86
917 次点击
所在节点    C
3 条回复
hitmanx
2015-07-16 17:16:47 +08:00
挺有意思的,我做了几个实验。

namespace NS_A
{
class A
{
public:
A(){std::cout << "A ctor" << std::endl;}
~A(){std::cout << "A dtor" << std::endl;}
};
}

namespace NS_B
{
void test()
{
NS_A::A* a = new NS_A::A;
a->~A(); // ok
operator delete(a);
}
}

int main()
{
NS_B::test();
return 0;
}
==============================
但是如果这儿加上一个typedef,情况就不一样了。

namespace NS_A
{
class A
{
public:
A(){std::cout << "A ctor" << std::endl;}
~A(){std::cout << "A dtor" << std::endl;}
};

typedef NS_A::A CloneA; // add typedef here
}


namespace NS_B
{
void test()
{
NS_A::CloneA* a = new NS_A::CloneA;
a->~CloneA(); // oops, we end up with compile error here
operator delete(a);
}
}

int main()
{
NS_B::test();
return 0;
}

===============================================
如果加上一句“using NS_A::CloneA;”,编译就又没有问题了。

同样的,string是一个typedef,原型是模板类basic_string的一个特化。如果这儿改成它的原型,比如改成以下这样,是可以编译的。

int main()
{
std::string *sp = new std::string("hehe");
sp->~basic_string(); // ok now
operator delete (sp);
return 0;
}
clapse
2015-07-16 21:59:23 +08:00
楼上举的例子:

a->~CloneA(); // oops, we end up with compile error here

此处编译器尝试去解释成 A::~CloneA(),没有成功

使用 using NS_A::CloneA;
或者 a->NS_A::CloneA::~CloneA();

此处编译器将~CloneA()替换成了~A(),编译通过

我这样理解对吗?
linux40
2015-07-17 07:51:19 +08:00
@clapse 具体不知道,一直觉得这种东西写编译器实现时会有更深刻的理解,析构函数在编译器眼里就是~加类型名,这里虽然是CloneA,但CloneA是typedef的,实际类型是A,所以析构函数应该是~A,而using的做用只是将名字在当前作用域可见,这样相互作用就成功了吧,个人乱想。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/206104

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX