久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

不同 C++ 文件中的相同類名

Same class name in different C++ files(不同 C++ 文件中的相同類名)
本文介紹了不同 C++ 文件中的相同類名的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

如果兩個 C++ 文件對同名類的定義不同,那么在編譯和鏈接時,即使沒有警告也會拋出一些東西.例如,

If two C++ files have different definitions of classes with the same name, then when they are compiled and linked, something is thrown out even without a warning. For example,

// a.cc
class Student {
public:
    std::string foo() { return "A"; }
};
void foo_a()
{
    Student stu;
    std::cout << stu.foo() << std::endl;
}

// b.cc
class Student {
public:
    std::string foo() { return "B"; }
};
void foo_b()
{
    Student stu;
    std::cout << stu.foo() << std::endl;
}

當使用 g++ 編譯和鏈接在一起時,兩者都會輸出A"(如果在命令行順序中 a.cc 在 b.cc 之前).

When compiled and linked together using g++, both will output "A" (if a.cc precedes b.cc in the command line order).

一個類似的主題是這里.我看到命名空間將解決這個問題,但我不知道為什么鏈接器甚至不發出警告.如果該類的一個定義具有另一個未定義的額外函數,假設 b.cc 更新為:

A similar topic is here. I see namespace will solve this problem but I don't know why the linker doesn't even shoot a warning. And if one definition of the class has extra function that isn't defined in another, say if b.cc is updated as:

// b.cc
class Student {
public:
    std::string foo() { return "B"; }
    std::string bar() { return "K"; }
};
void foo_b()
{
    Student stu;
    std::cout << stu.foo() << stu.bar() << std::endl;
}

然后 stu.bar() 運行良好.感謝任何能告訴我編譯器和鏈接器在這種情況下如何工作的人.

Then stu.bar() works well. Thanks to anyone who can tell me how the compiler and linker work in such situation.

另外一個問題,如果類是在頭文件中定義的,它們是否應該總是用未命名的命名空間包裝以避免這種情況?有副作用嗎?

As an extra question, if classes are defined in header files, should they always be wrapped with unnamed namespace to avoid such situation? Is there any side effects?

推薦答案

這違反了一個定義規則(C++03, 3.2/5 "One definition rule"),其中說(除其他外):

This is a violation of the one definition rule (C++03, 3.2/5 "One definition rule"), which says (among other things):

一個類類型可以有多個定義(第 9 條),...在一個程序中,只要每個定義出現在不同的翻譯單元,并提供定義滿足以下條件要求.給定這樣一個名為 D 的實體,定義在多個翻譯單元,然后

There can be more than one definition of a class type (clause 9), ... in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. Given such an entity named D defined in more than one translation unit, then

  • D 的每個定義都應由相同的記號序列組成;

如果你違反了一個定義規則,行為是未定義的(這意味著可能會發生奇怪的事情).

If you violate the one definition rule, the behavior is undefined (which means that strange things can happen).

鏈接器看到多個 Student::foo() 的定義——一個在 a 的目標文件中,一個在 b 的目標文件中.然而,它并沒有抱怨這一點;它只是選擇兩者之一(碰巧,它遇到的第一個).這種對重復函數的軟"處理顯然只適用于內聯函數.對于非內聯函數,鏈接器抱怨多個定義并拒絕生成可執行文件(可能有選項可以放寬此限制).GNU ld 和 MSVC 的鏈接器都以這種方式運行.

The linker sees multiple definitions of Student::foo() - one in a's object file and one in b's. However it doesn't complain about this; it just selects one of the two (as it happens, the first one it comes across). This 'soft' handling of duplicate functions apparently happens only for inline functions. For non-inline functions, the linker will complain about multiple definitions and will refuse to produce an executable (there may be options that relax this restriction). Both GNU ld and MSVC's linker behave this way.

這種行為是有道理的;內聯函數需要在它們使用的每個翻譯單元中可用.在一般情況下,它們需要有非內聯版本可用(以防調用未內聯或函數地址被占用).inline 實際上只是圍繞單一定義規則的免費傳遞 - 但要使其起作用,所有內聯定義都需要相同.

The behavior makes some sense; inline functions need to be available in every translation unit they're used in. And in the general case they need to have non-inline versions available (in case the call isn't inlined or if the function's address is taken). inline is really just a free pass around the one-definition rule - but for it to work, all the inline definitions need to be the same.

當我查看目標文件的轉儲時,我沒有看到任何明顯的東西向我解釋鏈接器如何知道允許一個函數具有多個定義而其他函數則不允許,但我確定有一些標志或記錄就是這樣做的.不幸的是,我發現鏈接器的工作原理和目標文件的詳細信息并沒有特別詳細的記錄,因此確切的機制可能對我來說仍然是個謎.

When I look at dumps of the object files, I don't see anything obvious that explains to me how the linker knows that one function is permitted to have multiple definitions and others aren't, but I'm sure there's some flag or record which does just that. Unfortunately, I find that the workings of the linker and object file details aren't particularly well documented, so the precise mechanism will probably remain a mystery to me.

至于你的第二個問題:

作為一個額外的問題,如果在頭文件中定義了類,應該它們總是用未命名的命名空間包裹以避免這種情況?有副作用嗎?

As an extra question, if classes are defined in header files, should they always be wrapped with unnamed namespace to avoid such situation? Is there any side effects?

您幾乎肯定不想這樣做,每個類在每個翻譯單元中都是一個不同的類型,因此從技術上講,不能將類的實例從一個翻譯單元傳遞到另一個(通過指針、引用或復制)).此外,您最終會得到任何靜態成員的多個實例.那可能不會奏效.

You almost certainly don't want to do this each class would be a distinct type in each translation unit, so technically instances of the class they couldn't be passed from one translation unit to another (by pointer, reference or copying). Also, you'd end up with multiple instances of any static members. That probably wouldn't work well.

將它們放在不同的命名空間中.

Put them in different, named namespaces.

這篇關于不同 C++ 文件中的相同類名的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

Assertion failed (size.widthgt;0 amp;amp; size.heightgt;0)(斷言失敗(size.width0 amp;amp; size.height0))
Rotate an image in C++ without using OpenCV functions(在 C++ 中旋轉圖像而不使用 OpenCV 函數)
OpenCV: process every frame(OpenCV:處理每一幀)
Why can#39;t I open avi video in openCV?(為什么我不能在 openCV 中打開 avi 視頻?)
OpenCV unable to set up SVM Parameters(OpenCV 無法設置 SVM 參數)
Convert a single color with cvtColor(使用 cvtColor 轉換單一顏色)
主站蜘蛛池模板: 亚洲欧美综合精品久久成人 | 久久99精品久久久97夜夜嗨 | 国产亚洲第一页 | 亚洲人在线观看视频 | 草逼网站| 黄色三级毛片 | 中文字幕精品一区二区三区精品 | 一区二区视频免费观看 | 久久久久久成人 | 色接久久| 亚洲精品一区二区久 | 午夜精品在线观看 | 欧美理伦片在线播放 | www.色综合 | 激情影院久久 | 天堂免费看片 | 欧美亚洲综合久久 | 夜夜摸天天操 | 91玖玖| 最新日韩在线 | 91亚洲国产精品 | 香蕉久久久久久 | 国产成人99久久亚洲综合精品 | 伊人av在线播放 | 久久久91精品国产一区二区三区 | 911网站大全在线观看 | 国产精品视频网址 | 久久亚洲经典 | 国产超碰人人爽人人做人人爱 | 视频一区二区在线观看 | 国产成人网| 国产免费一区二区 | 国产特级毛片 | 成人久久18免费网站麻豆 | 日本午夜一区二区三区 | 久久精品成人 | 中文字幕一区二区三区四区不卡 | 亚洲免费人成在线视频观看 | 日日夜精品视频 | 国产亚洲欧美在线 | 亚洲成人二区 |