【问题标题】:What is the scope of a class inside of a class in C++?C ++中类内部的类的范围是什么?
【发布时间】:2014-11-15 05:02:53
【问题描述】:

我写了一个看起来像这样的类

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;
}

或者有没有更好/更简单的方法来处理这个问题?

【问题讨论】:

  • 您的原件应该没问题。 push_backv 的副本存储在本地vs 中;并鉴于您声明Mesh 的方式,构建一个应该复制本地vs 及其所有元素。局部变量将超出范围并被销毁,但Mesh 中的副本是安全的。
  • 啊,抱歉,已解决。感谢您的回复!
  • 好像你在问函数内部对象的范围,而不是类内部的类范围。
  • 您确定不要std::vector&lt;Vertex&gt;
  • -1 不是真正的代码。即使添加了所有缺少的分号,此代码也不会编译。也就是说,忘记new:返回你想返回的任何东西,让编译器担心优化。添加代价高昂的动态分配和间接分配不一定是提高性能的最佳方式。

标签: c++ scope


【解决方案1】:

你的基本结构对我来说很合适。您将Vertex 复制到vector,然后将vector 复制到Meshload_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_backvector 中就地构造Vertex,并使用std::movevector 移动到Mesh

返回 shared_ptr&lt;Mesh&gt; 很好,但我想表明您也可以按值返回 Mesh。编译器应该执行RVO并且不会有副本(see this question)。

【讨论】:

  • 你的 Mesh-ctor 错过了&amp;&amp;
  • @Deduplicator,否 I've intentionally used pass-by-value。仅以额外的一步为代价,我只需要定义一个构造函数,但仍然可以绑定到右值或左值。是的,如果你愿意,你可以限制为右值。
  • @Deduplicator Mesh 确实需要一个副本,它需要它的成员变量。也许这是一个误导性的链接,试试this one:
  • 我不确定何时或是否生成移动构造函数。如果有明确指定的移动构造函数,我会更加确定代码。
  • @Cheersandhth.-Alf 是的,但是我必须定义一个普通的构造函数,实际上也是一个复制构造函数。为了简单起见,我可能只定义一个普通的构造函数并依赖emplace_back...
猜你喜欢
  • 2019-08-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
  • 1970-01-01
  • 2010-09-12
  • 1970-01-01
  • 2020-04-26
相关资源
最近更新 更多