在 Vector c++ 中使用指针成员初始化对象
Initialize Object with Pointer Members in a Vector c++
我希望在使用 push_back()
方法时能够在对象上调用非平凡的构造函数。相反,我所能做的就是将对象的浅表副本传递给向量。使用常规 C 风格数组时,创建数组时会自动调用构造函数,但由于向量是动态的,因此对象尚不存在。
如何在没有两个指针指向同一内存地址的情况下向向量添加一个新的空对象?我需要复制构造函数还是重载赋值运算符?
下面是一些演示我的问题的示例代码:
struct Object
{
int *Pointer;
Object()
{
Pointer = new int;
*Pointer = 42;
}
~Object()
{
delete Pointer;
}
};
int main()
{
std::vector <Object> *Array;
Array = new std::vector <Object>;
// Attempt 1
Array->push_back(Object());
// Attempt 2
{
Object LocalInstance;
Array->push_back(LocalInstance);
}
// Error here because the destructor has already been called for
// LocalInstance and for Object()
delete Array;
return 0;
}
@KonradRudolph 是正确的 - Array
没有理由成为此处的指针,它只会混淆代码。
你的代码崩溃的原因是 LocationInstance 被传递给 push_back
但你的 Object
没有合适的复制构造函数,所以只有 Pointer
成员的浅拷贝被复制。当 LocalInstance 超出范围时,该对象删除其 Pointer
但容器中的副本具有相同的 Pointer
,这导致在清理容器时删除释放的内存。
请查看 Rule-of-Five(在 C++11 之前是三规则)。
在将构造对象添加到容器中时,您使用的是 C++11 吗?如果是这样,您可以 emplace_back
并在添加对象时在容器中构建对象 - 这就是您想要做的吗?
这个简单的例子只给我一个 clang 的警告:
struct A
{
A(int a) : member_m(a)
{}
int &member_m;
};
int main() {
A a(1);
}
给我:
~/ClionProjects/so_reference_to_temporary $ clang++ -o test main.cpp
main.cpp:8:25: warning: binding reference member 'member_m' to stack allocated
parameter 'a' [-Wdangling-field]
A(int a) : member_m(a)
^
main.cpp:13:10: note: reference member declared here
int &member_m;
^
1 warning generated.
#include <iostream>
using namespace std;
// constructors examples
class myClass
{
private:
int* data;
public:
//constructor
myClass(int value)
{
data = new int ;
*data = value ;
}
//copy constructor
myClass (const myClass& other)
:myClass(*other.data)
{
}
//move constructor
myClass (myClass&& other)
:data(other.data)
{
other.data = nullptr ;
}
//destructor
~myClass ()
{
delete data ;
}
//copy assignment
myClass& operator=(myClass other)
{
std::swap (data, other.data);
return *this ;
}
};
int main ()
{
myClass M1(5);
myClass M2=M1;
myClass M3(M2);
M1 = M3;
myClass M4(std::move(M1));
return 0;
}
我希望在使用 push_back()
方法时能够在对象上调用非平凡的构造函数。相反,我所能做的就是将对象的浅表副本传递给向量。使用常规 C 风格数组时,创建数组时会自动调用构造函数,但由于向量是动态的,因此对象尚不存在。
如何在没有两个指针指向同一内存地址的情况下向向量添加一个新的空对象?我需要复制构造函数还是重载赋值运算符?
下面是一些演示我的问题的示例代码:
struct Object
{
int *Pointer;
Object()
{
Pointer = new int;
*Pointer = 42;
}
~Object()
{
delete Pointer;
}
};
int main()
{
std::vector <Object> *Array;
Array = new std::vector <Object>;
// Attempt 1
Array->push_back(Object());
// Attempt 2
{
Object LocalInstance;
Array->push_back(LocalInstance);
}
// Error here because the destructor has already been called for
// LocalInstance and for Object()
delete Array;
return 0;
}
@KonradRudolph 是正确的 - Array
没有理由成为此处的指针,它只会混淆代码。
你的代码崩溃的原因是 LocationInstance 被传递给 push_back
但你的 Object
没有合适的复制构造函数,所以只有 Pointer
成员的浅拷贝被复制。当 LocalInstance 超出范围时,该对象删除其 Pointer
但容器中的副本具有相同的 Pointer
,这导致在清理容器时删除释放的内存。
请查看 Rule-of-Five(在 C++11 之前是三规则)。
在将构造对象添加到容器中时,您使用的是 C++11 吗?如果是这样,您可以 emplace_back
并在添加对象时在容器中构建对象 - 这就是您想要做的吗?
这个简单的例子只给我一个 clang 的警告:
struct A
{
A(int a) : member_m(a)
{}
int &member_m;
};
int main() {
A a(1);
}
给我:
~/ClionProjects/so_reference_to_temporary $ clang++ -o test main.cpp
main.cpp:8:25: warning: binding reference member 'member_m' to stack allocated
parameter 'a' [-Wdangling-field]
A(int a) : member_m(a)
^
main.cpp:13:10: note: reference member declared here
int &member_m;
^
1 warning generated.
#include <iostream>
using namespace std;
// constructors examples
class myClass
{
private:
int* data;
public:
//constructor
myClass(int value)
{
data = new int ;
*data = value ;
}
//copy constructor
myClass (const myClass& other)
:myClass(*other.data)
{
}
//move constructor
myClass (myClass&& other)
:data(other.data)
{
other.data = nullptr ;
}
//destructor
~myClass ()
{
delete data ;
}
//copy assignment
myClass& operator=(myClass other)
{
std::swap (data, other.data);
return *this ;
}
};
int main ()
{
myClass M1(5);
myClass M2=M1;
myClass M3(M2);
M1 = M3;
myClass M4(std::move(M1));
return 0;
}