[英]Why can I define structures and classes within a function in C++?
我只是錯誤地在 C++ 中做了這樣的事情,它可以工作。 為什么我可以這樣做?
int main(int argc, char** argv) {
struct MyStruct
{
int somevalue;
};
MyStruct s;
s.somevalue = 5;
}
[編輯 18\/4\/2013]:<\/strong>令人高興的是,下面提到的限制在 C++11 中已經解除,所以本地定義的類畢竟是有用的! 感謝評論者竹子。
本地定義類的能力將使<\/em>創建自定義函子(具有
operator()()<\/code>的類,例如用於傳遞給
std::sort()<\/code>的比較函數或與
std::for_each()<\/code>一起使用的“循環體”)很多更方便。
不幸的是,C++ 禁止將本地定義的類與模板一起使用<\/strong>,因為它們沒有鏈接。 由於函子的大多數應用程序都涉及在函子類型上模板化的模板類型,因此不能使用本地定義的類——您必須在函數之外定義它們。 :(
[編輯 2009 年 1 月 11 日]<\/strong>
該標准的相關報價是:
14.3.1\/2:<\/strong>本地類型、無鏈接類型、未命名類型或由這些類型中的任何一種復合的類型不得用作模板類型參數的模板參數。
本地定義的 C++ 類的一種應用是工廠設計模式:
// In some header
class Base
{
public:
virtual ~Base() {}
virtual void DoStuff() = 0;
};
Base* CreateBase( const Param& );
// in some .cpp file
Base* CreateBase( const Params& p )
{
struct Impl: Base
{
virtual void DoStuff() { ... }
};
...
return new Impl;
}
盡管您可以對匿名命名空間執行相同的操作。
它實際上對於做一些基於堆棧的異常安全工作非常有用。 或者從具有多個返回點的函數中進行一般清理。 這通常被稱為 RAII(資源獲取即初始化)習語。
void function()
{
struct Cleaner
{
Cleaner()
{
// do some initialization code in here
// maybe start some transaction, or acquire a mutex or something
}
~Cleaner()
{
// do the associated cleanup
// (commit your transaction, release your mutex, etc.)
}
};
Cleaner cleaner;
// Now do something really dangerous
// But you know that even in the case of an uncaught exception,
// ~Cleaner will be called.
// Or alternatively, write some ill-advised code with multiple return points here.
// No matter where you return from the function ~Cleaner will be called.
}
好吧,基本上,為什么不呢? C 中的
struct<\/code> (可以追溯到時間的黎明)只是聲明記錄結構的一種方式。
如果你想要一個,為什么不能在你聲明一個簡單變量的地方聲明它呢?
一旦你這樣做了,請記住 C++ 的目標是盡可能與 C 兼容。 於是就留了下來。
它用於制作正確初始化的對象數組。
我有一個沒有默認構造函數的 C 類。 我想要一個 C 類的對象數組。我弄清楚我希望如何初始化這些對象,然后使用靜態方法從 C 派生一個 D 類,該方法為 D 的默認構造函數中的 C 提供參數:
#include <iostream>
using namespace std;
class C {
public:
C(int x) : mData(x) {}
int method() { return mData; }
// ...
private:
int mData;
};
void f() {
// Here I am in f. I need an array of 50 C objects starting with C(22)
class D : public C {
public:
D() : C(D::clicker()) {}
private:
// I want my C objects to be initialized with consecutive
// integers, starting at 22.
static int clicker() {
static int current = 22;
return current++;
}
};
D array[50] ;
// Now I will display the object in position 11 to verify it got initialized
// with the right value.
cout << "This should be 33: --> " << array[11].method() << endl;
cout << "sizodf(C): " << sizeof(C) << endl;
cout << "sizeof(D): " << sizeof(D) << endl;
return;
}
int main(int, char **) {
f();
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.