簡體   English   中英

自動定義的變量的C ++ 11類型

[英]C++11 types for variables defined with auto

我正在閱讀Bjarne Stroustrup的書《 C ++編程語言》,在3.2.4節中,他演示了從抽象類開始的類層次結構。 他的代碼如下所示:

class Shape
{
public:
    virtual Point center()const = 0; //Point is a class defined elsewhere and is unimportant for this question
    virtual void move(Point to) = 0;

    virtual void draw()const = 0;
    virtual void rotate(int angle) = 0;
}

class Circle: public Shape
{
    //overrides functions
}

void rotate_all(vector<Shape*>& v, int angle)
{
    for(auto p:v)
        p->rotate(angle);
}

我的問題是:用Circle對象的向量調用函數rotate_all時, p變量是什么類型? 如果它是Shape ,那么這些對象不會切成通用的Shape對象嗎? 如果它是一個Circle ,那么該函數僅適用於Circle對象的矢量,而不適用於Shape類的其他子類嗎?

從不使用“ Circle對象的向量”來調用rotate_all() 它的第一個參數始終是對std::vector<Shape*>的引用。

最棘手的部分是,這種類型的這種載體不一定必須反映存儲中-因為你可以把它付諸表決指向任何類,從繼承Shape (技術/思想上來講,這也許應該轉換成“ 公開的繼承Shape ,但保留該Shape )。

而且,此向量將永遠不會存儲 Shape任何實例,因為它是一個抽象類,因此它的實例化被禁止。

因此,舉例說明:

class Circle: public Shape
{
    //cut
    virtual void draw() const override { printf("Circle!\n"); }
}

//add another class
class Square: public Shape
{
    //cut
    virtual void draw() const override { printf("Square!\n"); }
}

void draw_all(vector<Shape*>& v, int angle)
{
    for(auto p : v)
        p->draw(); //p is an iterator pointing internally to Shape*
}

Shape* c = new Circle();
Shape* s = new Square();

std::vector<Shape*> v;

v.push_back(c);
v.push_back(s);

draw_all(v);

輸出:

Circle!
Square!

簡單地說: Shape*在這里用於輕松引入多態行為以收集對象。

基於范圍的for循環將從以下內容擴展:

for ( range_declaration : range_expression ) loop_statement

{
    auto && __range = range_expression ; 
    for (auto __begin = begin_expr, __end = end_expr;  __begin != __end; ++__begin) { 
        range_declaration = *__begin; 
        loop_statement 
    } 
}

因此,此處在for循環中聲明的auto變量設置為開始迭代器的值,在您的情況下,該值是Shape* 由於它是指針,因此不會切片,否則將無法進行多態。

這是value_type容器在大多數情況下(或更為精准,取消引用的結果begin ),這對於你的矢量Shape*等為指針,沒有切割的風險。

當您要迭代包含值但又不想復制它們(因為要對其進行突變,性能,無復制構造函數等)時,也可以使用auto &p

http://en.cppreference.com/w/cpp/language/range-for對遠程正是對循環擴展到了,怎么確定陣列范圍的詳細信息,以班級begin成員,並使用ADL begin除此以外。 實際值類型是取消引用“迭代器”的結果,而C ++ auto僅采用該右側類型。

順便說一句,至少在Visual Studio 2015中(不要為其他人記住),如果將鼠標懸停在聲明為auto的變量上,它將嘗試向您顯示實際類型,如果將鼠標懸停在“ auto”上(例如,向我展示了std :: vector typedef)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM