假設我有一個類,您可以在下面看到(也請閱讀評論):
Foo.h
#pragma once
namespace Bar
{
class Foo
{
public:
inline Foo( );
private:
char c;
inline static const std::unordered_set<char> CHAR_SET {'/', '\\', '|', '-'};
friend class Invalid_C_Exception;
};
} // end of namespace Bar
我有:
Foo.cpp
#include "Foo.h"
using namespace Bar;
inline Foo::Foo( )
{
}
class Invalid_C_Exception : public std::exception
{
public:
virtual const char* what( ) const throw( )
{
std::stringstream ss;
ss << "Invalid_C_Exception: { ";
// compiler gives an error here because of usages of CHAR_SET
for ( auto it = Foo::CHAR_SET.cbegin( ); it != Foo::CHAR_SET.cend( ); it )
{
ss << "'" << *it << "', ";
}
return somehow_save_the_C_string(ss.str());
}
} Invalid_C_Exc;
第一個問題:
全域Invalid_C_Exc變數的存在好嗎?
第二個問題:
為什么編譯器CHAR_SET在嘗試編譯時指責我是私有的Foo.cpp?
自定義例外類,盡管是 class 的朋友,但Foo無法訪問CHAR_SET?
第三個問題:
我應該把這些自定義例外類放在哪里?在單獨的頭檔案和源檔案中,但在相同的命名空間下?
我猶豫不決,所以我將宣告和實作放在源檔案中,Foo.cpp因為例外類旨在為該類作業Foo,因此它們彼此相關。
uj5u.com熱心網友回復:
第一個問題:這個變數的存在可以嗎?
全域變數通常不是一個好主意,并且由于例外物件在拋出時會被復制到專用的例外存盤中,因此我認為這個特定的全域變數沒有任何用處。
第二個問題是為什么編譯器會因為 CHAR_SET 是私有的而責怪我
您已經定義了一個類Bar::Foo并宣告了它的友元類Bar::Invalid_C_Exception……但是您根本沒有在實作檔案中觸及它們。您剛剛在全域命名空間中宣告了一個新的且不相關 Invalid_C_Exception的。
洗掉using namespace Bar并包裝包含下面的所有內容,namespace Bar { ... }與標題中的內容相同。或者Bar::Foo,Bar::Invalid_C_Exception如果您愿意,可以在任何地方明確地寫。
該using namespace指令使得名字從命名空間的封閉范圍可見。它不會將添加到封閉范圍內的所有內容都吸回到命名空間中。如果您有多個using namespace指令,這將如何作業?為什么會using namespace std;被允許?
第三個問題:我應該把這些自定義例外類放在哪里?
好吧,如果您希望任何人都能夠使用它,則不能將定義放在您的實作檔案中。只需將類定義放在頭檔案中,只Bar::Invalid_C_Exception::what在實作檔案中保留 的定義。
它們是否與它們的朋友類放在同一個頭檔案和實作檔案中取決于您,這并不重要。
第四個問題:每個問題我應該問多少個問題?
一。它被稱為問題,而不是問卷。
uj5u.com熱心網友回復:
之間有很大的區別
friend class Invalid_C_Exception;
和
friend Invalid_C_Exception;
后者期望Invalid_C_Exception已經存在于某個可訪問的地方,并使該符號成為 的朋友Foo。前者Invalid_C_Exception 在封閉范圍內宣告了一個新符號并使之成為新朋友。
這意味著您已經與 成為Bar::Invalid_C_Exception了朋友Foo,而不是::Invalid_C_Exception您稍后定義的仍然不是朋友的全域變數。Bar::Invalid_C_Exception永遠不會存在的事實是無關緊要的。
關于你的第一個問題,Invalid_C_Exc是一個全域變數,默認情況下它有外部鏈接。如果僅在此翻譯單元(.cpp 檔案)中使用它static,請將其制作或放入匿名命名空間。我建議不要偷懶,將其定義寫在單獨的行上,這樣會更清晰。除此之外,你可以很好地使用它,它在main開始之前被初始化并一直持續到程式結束。
關于你的第三個問題。無論您想要什么,我通常都會建議.hpp每種例外型別或一組緊密組合的例外型別。把它放進.cpp去很難抓住它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/350360.html
