提问人:EmbeddedDOOD 提问时间:8/26/2022 更新时间:8/26/2022 访问量:154
将大量内存传递给类的构造函数的正确方法是什么?
What is the proper way to pass a large amount of memory to a constructor for a class?
问:
对于此示例,请考虑这两个类。
第一个类定义一个具有单个公共成员的简单类。
class Tester
{
public:
int m_tester_value;
Tester(){}
Tester(int test_val)
{
m_tester_value = test_val;
}
Tester(const Tester & data) : m_tester_value(data.m_tester_value)
{
std::cout << "Tester Copied!" << std::endl;
}
Tester& operator=(const Tester & data)
{
m_tester_value = data.m_tester_value;
return *this;
}
};
第二个类还定义了一个具有单个公共成员的简单类,但此成员是第一个类中的对象向量。Tester
class VectorTester
{
public:
std::vector<Tester> m_vector;
VectorTester(std::vector<Tester>* vector_construct)
{
if(vector_construct != nullptr)
{
m_vector = *vector_construct;
}
}
VectorTester(const VectorTester & data) :
m_vector(data.m_vector)
{
std::cout << "VectorTester Copied!" << std::endl;
}
};
我相信我正在尝试在类中复制向量。VectorTester
我编写了一个简单的函数,它将为我生成一个。vector<Tester>
std::vector<Tester> TesterVectorGenerator(void)
{
std::vector<Tester> ret_vector;
ret_vector.reserve(2);
ret_vector.emplace_back(65);
ret_vector.emplace_back(75);
return ret_vector;
}
为了测试此代码,我使用了此示例。
int main() {
std::vector<Tester> my_test_vector = TesterVectorGenerator();
VectorTester vector_test = VectorTester(&my_test_vector);
for (const auto &i : vector_test.m_vector)
{
// access by value, the type of i is int
std::cout << "VectorTester.m_vector:" << i.m_tester_value << std::endl;
}
for (const auto &i : my_test_vector)
{
// access by value, the type of i is int
std::cout << "my_test_vector:" << i.m_tester_value << std::endl;
}
}
一切似乎都按预期工作,输出如下所示:
Tester Copied!
Tester Copied!
VectorTester.m_vector:65
VectorTester.m_vector:75
my_test_vector:65
my_test_vector:75
问题 1:这是将大量数据传递到类中的最佳方式吗?由于指针只有 4 个字节的内存,我认为这比将整个值传递到类中并以这种方式复制它要好。
问题 2:对于这种为 C++ 传递数据的做法,是否有任何标准的习语?
感谢您对问题和手头代码的任何回复和输入。我对C++比较陌生,我很感激任何帮助!
答:
第1项质询
复制构造函数与准婚指针构造函数(即)一样有效,但更安全,因为引用不能是 .编译后,引用可能只是指向编译器的指针(参见:[https://www.godbolt.org/z/qsWdr4qTc])。因此,如果您希望将所有资源从一个对象/类型/类复制到另一个对象/类型/类,请使用复制构造函数,因为它比指针版本更安全且速度更快。至于对象资源复制的效率,这取决于你如何进行复制。在你的例子中,使用 std::vectors
复制构造函数(就像你已经拥有的一样)可能是最有效的。VectorTester(std::vector<Tester>* vector_construct)
nullptr
第2项质询
在 C++ 中,有几种类型的构造函数,最著名的是默认构造函数、复制构造函数和移动构造函数。有一些特定的语义用于指定哪个构造函数是哪个构造函数。
- 默认 - 将对象及其资源初始化为默认状态。
- 复制 - 复制其他对象的状态,并将数据从其资源复制到新对象。
- 移动 - 克隆其他对象的状态,并将其资源的所有权移动到新对象,使另一个对象处于默认状态的未指定状态。
- 参数化构造函数 - 使用显式参数来初始化对象(例如,用于为数据结构类型保留内存的大小构造函数)。
- Initializer List 构造函数 - 用于初始化对象。
std::initializer_list
下面是一个示例类,其中实现了前三个构造函数签名,这些签名与您的问题最相关。
class A
{
private:
int i;
public:
/// Default Constructor
A()
: i(0) {};
/// Copy Constructor
A(const A& a)
: i(a.i) {};
/// Move Constructor
A(A&& a)
: i(a.i)
{ a.i = 0; }; ///< Leaves `a` in default state
};
上面示例中的签名是 C++ 中指定默认、复制和移动构造函数的最惯用方式 C++.在这里看到它的实际效果。
评论