是否有可能在不聲明C++的情況下聲明一個變量?我想要做這樣的事情:在C++初始化之前聲明一個對象
Animal a;
if(happyDay())
a("puppies"); //constructor call
else
a("toads");
Basially,我只想因此它的權利範圍申報條件的外面。
有沒有辦法做到這一點,而不使用指針並在堆上分配a
?也許聰明的引用?
是否有可能在不聲明C++的情況下聲明一個變量?我想要做這樣的事情:在C++初始化之前聲明一個對象
Animal a;
if(happyDay())
a("puppies"); //constructor call
else
a("toads");
Basially,我只想因此它的權利範圍申報條件的外面。
有沒有辦法做到這一點,而不使用指針並在堆上分配a
?也許聰明的引用?
你不能這樣直接在C,因爲當你使用默認的構造函數定義它的對象構造做++。
你可以,但是,運行參數的構造函數來開始:
Animal a(getAppropriateString());
或者你實際上可以使用類似的?: operator
,以確定正確的字符串。 (更新:@Greg給出了這個語法,看到這個答案)
是的,你可以不執行以下操作:
Animal a;
if(happyDay())
a = Animal("puppies");
else
a = Animal("toads");
這將正確地調用構造函數。
編輯:忘了一件事... 當聲明一個,你必須仍然調用一個構造函數,無論它是一個什麼都不做的構造函數,或者仍然初始化值爲任何東西。因此該方法創建兩個對象,一個在初始化時,另一個在if語句內。
一種更好的方式是創建該類的一個init()函數,如:
Animal a;
if(happyDay())
a.init("puppies");
else
a.init("toads");
這樣會更有效。
如果不調用構造函數,則不能聲明變量。然而,在你的例子,你可以做到以下幾點:
Animal a(happyDay() ? "puppies" : "toads");
你不能在這裏使用引用,因爲只要你離開範圍,引用就會指向一個對象,被刪除。
真的,你有兩個選擇:
1的指針轉到:
Animal* a;
if(happyDay())
a = new Animal("puppies"); //constructor call
else
a = new Animal("toads");
// ...
delete a;
2-添加init方法來Animal
:
class Animal
{
public:
Animal(){}
void Init(const std::string& type)
{
m_type = type;
}
private:
std:string m_type;
};
Animal a;
if(happyDay())
a.Init("puppies");
else
a.Init("toads");
我會親自去與選項2.
我更喜歡格雷格的答案,但你也可以這樣做:
char *AnimalType;
if(happyDay())
AnimalType = "puppies";
else
AnimalType = "toads";
Animal a(AnimalType);
我建議這樣做是因爲我曾經在那些條件運算符被禁止的地方工作。 (嘆氣!)另外,這可以很容易地擴展到兩種選擇之外。
除了格雷格Hewgill的回答,還有一些其他選項:
提升了代碼的主體爲一個功能:
void body(Animal & a) {
...
}
if(happyDay()) {
Animal a("puppies");
body(a);
} else {
Animal a("toad");
body(a);
}
(AB)使用放置新:
struct AnimalDtor {
void *m_a;
AnimalDtor(void *a) : m_a(a) {}
~AnimalDtor() { static_cast<Animal*>(m_a)->~Animal(); }
};
char animal_buf[sizeof(Animal)]; // still stack allocated
if(happyDay())
new (animal_buf) Animal("puppies");
else
new (animal_buf) Animal("toad");
AnimalDtor dtor(animal_buf); // make sure the dtor still gets called
Animal & a(*static_cast<Animal*>(static_cast<void*>(animal_buf));
... // carry on
如果你想避免垃圾收集 - 你可以使用智能指針。
auto_ptr<Animal> p_a;
if (happyDay())
p_a.reset(new Animal("puppies"));
else
p_a.reset(new Animal("toads"));
// do stuff with p_a-> whatever. When p_a goes out of scope, it's deleted.
如果你仍然想使用。語法代替 - >,你可以在上面的代碼之後執行此操作:
Animal& a = *p_a;
// do stuff with a. whatever
最好的解決方法是使用指針。
Animal a*;
if(happyDay())
a = new Animal("puppies"); //constructor call
else
a = new Animal("toads");
看到RAII(資源採集是初始化) – newacct 2009-04-29 00:57:03
,如果它是一個非靜態全局/命名空間範圍,那麼它是值得大家注意的,你可以不初始化它實際上宣告:EXTERN動物; ...動物(東西); – 2009-04-29 14:25:58
@newacct:一個鏈接將有助於https://stackoverflow.com/questions/2321511/what-is-meant-by-resource-acquisition-is-initialization-raii – spinkus 2014-06-10 22:08:24