2014-09-20 35 views
0

我寫了一個類,看起來像C++中類的範圍是什麼?

class Mesh { 
    public: 
     vector<Vertex> vs; 
} 

其中Vertex

class Vertex { 
    public: 
     const double x, y, z; 
} 

我有一個從文件加載Mesh功能:

shared_ptr<Mesh> load_mesh(string filename) { 
    //.... 
    vector<Vertex> vs; 
    Vertex v(1, 2, 3); 
    vs.push_back(v); 
    return shared_ptr<Mesh>(Mesh(vs)); 
} 

我的問題是涉及Vertexvector的範圍。

一個或兩個是否會超出範圍?

哪個(如果有的話)替代品是首選?

class Mesh1 { 
    public: 
     vector<shared_ptr<Vertex>> vs; 
} 


class Mesh2 { 
    public: 
     shared_ptr<vector<Vertex>> vs; 
} 


class Mesh3 { 
    public: 
     shared_ptr<vector<shared_ptr<Vertex>>> vs; 
} 

或者是否有更好/更簡單的方法來處理?

+2

你的原稿應該沒問題。 'push_back'在本地'vs'中存儲'v'的副本;並且考慮到你聲明'Mesh'的方式,構造一個應該複製本地'vs'及其所有元素。局部變量將超出範圍並被銷燬,但「Mesh」中的副本是安全的。 – 2014-09-20 21:54:23

+0

啊,對不起,修正了這個問題。感謝您的迴應! – sdasdadas 2014-09-20 21:57:31

+4

好像你在問函數內的對象的範圍,而不是類內類的範圍。 – 2014-09-20 22:00:14

回答

1

您的基本結構對我來說很合適。您正在將Vertex複製到vector中,然後將vector複製到Mesh中。 load_mesh()函數中的本地副本將超出範圍,但因爲您製作的副本沒有問題。

在被指責爲過早優化的風險我會說,除非vector是小,所有這些複製是有點低效。有很多方法可以優化。隨着C++ 11,和move semantics,你可以保持當前的結構,只是移動數據:

#include <vector> 

struct Vertex { 
    const double x, y, z; 
    Vertex(double _x, double _y, double _z) : x(_x), y(_y), z(_z) {} 
}; 

struct Mesh { 
    std::vector<Vertex> vs; 
    Mesh(std::vector<Vertex> _vs) : vs(std::move(_vs)) {} 
    Mesh(Mesh&& other) noexcept : vs(std::move(other.vs)) {} // Move constructor 
}; 

Mesh 
loadMesh() { 
    //.... 
    std::vector<Vertex> vs; 
    vs.emplace_back(1,2,3); 
    return Mesh{std::move(vs)}; 
} 

int main() { 
    auto mesh = loadMesh(); 
} 

我使用emplace_back代替push_back構建在vector就地和使用Vertexstd::movevector轉換爲Mesh

返回shared_ptr<Mesh>會很好,但我想告訴你也可以按價值返回Mesh。編譯器應該執行RVO並且將不存在副本(see this question)。

+0

Your Mesh-ctor錯過'&&'。 – Deduplicator 2014-09-20 23:09:16

+0

@Deduplicator,沒有[我有意使用傳遞值](http://stackoverflow.com/questions/7592630/is-pass-by-value-a-reasonable-default-in-c11)。只需要額外的一次移動,我只需要定義一個構造函數,但仍然可以綁定到右值或左值。是的,如果你願意,你可以限制在右值。 – 2014-09-20 23:14:30

+0

@Deduplicator'Mesh'確實需要一個副本,它需要它的成員變量。也許這是一個誤導性的鏈接,試試[這一個](http://stackoverflow.com/questions/21963062/best-way-to-write-constructor-of-a-class-who-holds-a-stl-container -in-c11): – 2014-09-20 23:22:25