struct Foo
{
Foo(int i)
{
ptr = new int(i);
}
~Foo()
{
delete ptr;
}
int* ptr;
};
int main()
{
{
Foo a(8);
Foo b(7);
a = b;
}
//Do other stuff
}
Run Code Online (Sandbox Code Playgroud)
如果我理解正确,编译器将自动为其创建赋值运算符成员函数Foo.但是,这只需要输入ptrin 的值b并将其放入a.a最初分配的内存似乎丢失了.我可以a.~Foo();在进行赋值之前进行调用,但我听说你应该很少需要显式调用析构函数.所以让我们说我编写一个赋值运算符Foo,删除int左操作数的指针,然后将r值赋给l值.像这样:
Foo& operator=(const Foo& other)
{
//To handle self-assignment:
if (this != &other) {
delete this->ptr;
this->ptr = other.ptr;
}
return *this;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我这样做,那么当Foo a和Foo …
我目前正在阅读Head First Object Oriented Analysis and Design这本书,同时也习惯了C++ 11的一些特性(特别是unique_ptr和移动语义).在书中,他们以策略棋盘游戏的设计为例.它有一块板,瓷砖和瓷砖单位.代码是用Java编写的,我试图用C++重写它.在Java中,tile类如下:
public class Tile
{
private List units;
public Tile()
{
units = new LinkedList();
}
protected void addUnit(Unit unit)
{
units.add(unit);
}
protected List getUnits()
{
return units;
}
}
Run Code Online (Sandbox Code Playgroud)
我首先使用shared_ptr在c ++中做了同样的事情.与使用原始指针的第二个版本相比,它工作但非常慢.然后我尝试了unique_ptr:
class Tile
{
public:
Tile();
virtual ~Tile();
void addUnit()
{
mUnits.push_back(std::unique_ptr<Unit>(new Unit());
}
std::vector<std::unique_ptr<Unit>> getUnits()
{
return mUnits;
}
private:
std::vector<std::unique_ptr<Unit>> mUnits;
};
Run Code Online (Sandbox Code Playgroud)
编译器不喜欢getUnits.据我所知,它来自于unique_ptr中禁用了复制构造函数的事实.你会如何返回向量列表?谢谢!
我有一个简单而又令人生畏的问题,我自己无法解决.我有类似的东西
template<class T, class... Args>
T* create(SomeCastableType* args, size_t numArgs)
{
return new T(static_cast<Args>(args[INDEX_OF_EXPANSION])...);
}
Run Code Online (Sandbox Code Playgroud)
假设SomeCastableType可以转换为任何类型.显然我不能得到的是INDEX_OF_EXPANSION.
非常感谢您的帮助.
昨天我问了一个关于在C#中复制对象的问题,大多数答案都集中在深拷贝和浅拷贝之间的区别,以及应该弄清楚两个拷贝变体中的哪一个给定拷贝构造函数(或运算符或函数)的事实.实现.我发现这很奇怪.
我用C++编写了很多软件,这种语言很大程度上依赖于复制,我从来不需要多种复制变体.我用过的唯一一种复制操作是我称之为" 足够深的复制 ".它执行以下操作:
现在,我的问题有三个:
我是C++ 11的一些代码.我有
class X { /* */ };
class A {
std::vector<X*> va_x;
};
class B {
std::vector<X*> vb_x;
std::vector<A> vb_a;
};
Run Code Online (Sandbox Code Playgroud)
我的类A中的"va_x"的X*s指向我的类B中"vb_x"的X*s指向的对象.
现在我想使用智能指针.对我来说,似乎很清楚,B类拥有X*指向的对象的所有权(特别是因为我的A实例属于B)
所以我应该在B中使用unique_ptr for X:
class B {
std::vector<unique_ptr<X>> vb_x;
std::vector<A> vb_a;
};
Run Code Online (Sandbox Code Playgroud)
我的问题是,我应该为A班做些什么?我应该保留原始指针吗?通过这样做,在我的单元测试中,我必须承认它导致尴尬的事情(imo),例如(不要担心封装,这不是重点):
unique_ptr<X> x(new X());
A a;
a.va_x.push_back(&(*x)); //awkward, but what else can I do?
A.vb_a.push_back(a); //ok
B.vb_x.push_back(move(x)); //ok
Run Code Online (Sandbox Code Playgroud) 这不是一个"怎么做"的问题,而是"如何正确地做到这一点"
我正在Qt中开发一个编辑器,其中不同的小部件显示子项及其(成员)变量.这些小部件中的每一个都应该包含一个指向已编辑子节点的引用/指针,以显示和更改其成员变量.
第一次尝试是旧的ANSI C方式,我学习(并且仍然有点卡住)使用简单的原始指针指向使用过的对象.它工作正常,但由于C++ 11标准支持智能指针,建议使用它们我试图使用它们.
问题是,我不太确定在这种情况下使用它们的"最佳方式"是什么...阅读智能指针后:或者谁拥有你的宝贝?和哪一种指针的我时使用?还有一些我得出了不同的结论:
第一种是使用a,*unique_ptr因为编辑的对象显然是创建并删除其子对象的所有者.小部件只是指孩子显示或更改它们.问题是小部件应该如何引用孩子......
现在我只是仍然使用我用get()方法获得的原始指针,unique_ptr但这对我来说似乎有点瑕疵.我仍然可以意外调用指针上的删除并取消智能指针的好处.
第二种方法是使用a,shared_ptr因为许多对象引用子进程并对其进行编辑.在一个小部件中意外删除它也不会有害,因为它仍归其他对象所有.问题是他们拥有它.当我想从编辑过的对象中删除它时,我还必须发信号通知所有小部件,以便在它真正消失之前将其删除.(这似乎又有缺陷且容易出错)
我对两种方式都不满意.是否有一种干净的(呃)方式指向unique_ptr对象的孩子?或者我错过了一个完全不同的更好的方法来解决这个问题?
可能重复:
我使用哪种指针?
有许多专业人士赞成C++ 11的智能指针:它们更安全,功能更强,范围更明显等.
"经典"C是否像指针一样
class C{};
C c;
C* c_p = &c;
Run Code Online (Sandbox Code Playgroud)
现在已经过时了?他们甚至被弃用了吗?或者是否存在C指针仍然有意义的用例?
编辑:带有智能指针的代码片段:
class C{};
C c;
std::shared_ptr<C> c_p(new C());
Run Code Online (Sandbox Code Playgroud)
编辑:感谢您指出副本.从Xeo的回答:
使用哑指针(原始指针)或对资源的非拥有引用的引用,当>你知道资源将比引用对象/范围更长时.当您需要可空性或可重置性时,首选引用和>使用原始指针.
如果这就是全部,我接受这个问题已被关闭.
问题:是否有任何令人信服的理由将裸指针用于非拥有资源,或者我们应该使用weak_ptr?
CPP.参考状态
std::weak_ptr模型临时所有权:当对象只有存在时才需要访问,并且可以随时被其他人删除
但是,在接受的答案中,我何时使用哪种指针?我们有以下声明:
对资源的非拥有引用使用哑指针(原始指针)或引用,并且当您知道资源将超过引用对象/范围时。当您需要可空性或可重置性时,更喜欢引用并使用原始指针.... a
shared_ptr并使用 aweak_ptr。
这个答案后面有很多关于使用裸指针的反复讨论,没有真正的解决方案。我看不出使用哑指针的任何理由。我错过了什么吗?
我正在分析代码,我对特定代码感到困惑.我发布了代码/伪代码,它们将传达相同的含义.
1级
Class1::Func1()
{
Collection* cltn;
try
{
cltn = Class2::get_records_from_db();
}
catch(Informix error)
{}
catch(DB Error)
{}
catch(...)
{ Unknown exception } //I get this error always once the process processes lot of records
}
Run Code Online (Sandbox Code Playgroud)
2级
Collection* Class2::get_records_from_db()
{
Collection *clt = new Collection();
try
{
//Query database
For each row in query result
Row *row = new row();
populate(row)
clt->add(*row)
...
if( Informix error)
{
throw Informix error;
}
}
catch(...)
{
delete clt; //Who will delete row? …Run Code Online (Sandbox Code Playgroud) c++ ×9
c++11 ×5
pointers ×3
unique-ptr ×3
copy ×1
deep-copy ×1
dynamic ×1
memory-leaks ×1
ownership ×1
reference ×1
shallow-copy ×1
templates ×1
vector ×1