相关疑难解决方法(0)

这个C++代码是否会泄漏内存?

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 aFoo …

c++ memory-leaks assignment-operator

19
推荐指数
2
解决办法
813
查看次数

从函数返回unique_ptr的向量

我目前正在阅读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中禁用了复制构造函数的事实.你会如何返回向量列表?谢谢!

c++ vector unique-ptr c++11

18
推荐指数
1
解决办法
8612
查看次数

可变参数模板扩展期间的C++索引类型

我有一个简单而又令人生畏的问题,我自己无法解决.我有类似的东西

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++ templates variadic-templates c++11

18
推荐指数
1
解决办法
5721
查看次数

复制构造函数/操作符/函数是否需要明确它实现的副本变体?

昨天我问了一个关于在C#中复制对象的问题,大多数答案都集中在深拷贝浅拷贝之间的区别,以及应该弄清楚两个拷贝变体中的哪一个给定拷贝构造函数(或运算符或函数)的事实.实现.我发现这很奇怪.

我用C++编写了很多软件,这种语言很大程度上依赖于复制,我从来不需要多种复制变体.我用过的唯一一种复制操作是我称之为" 足够深的复制 ".它执行以下操作:

  • 如果对象拥有成员变量的所有权(参见合成),则会以递归方式复制它.
  • 如果对象对成员变量没有所有权(参见聚合),则仅复制链接.

现在,我的问题有三个:

  • 1)对象是否需要多个副本变体?
  • 2)复制功能是否需要明确它实现的复制变体?
  • 3)顺便说一句,对于我称之为"足够深的复制品",是否有一个更好的术语?我问了一个关于"深层复制"这个术语定义的相关问题.

language-agnostic copy deep-copy shallow-copy

13
推荐指数
3
解决办法
1955
查看次数

否则使用unique_ptr用于所有权和原始指针?

我是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)

c++ ownership unique-ptr c++11

8
推荐指数
1
解决办法
1万
查看次数

C++ 11非拥有引用/指向unique_ptr的指针?

这不是一个"怎么做"的问题,而是"如何正确地做到这一点"

我正在Qt中开发一个编辑器,其中不同的小部件显示子项及其(成员)变量.这些小部件中的每一个都应该包含一个指向已编辑子节点的引用/指针,以显示和更改其成员变量.

第一次尝试是旧的ANSI C方式,我学习(并且仍然有点卡住)使用简单的原始指针指向使用过的对象.它工作正常,但由于C++ 11标准支持智能指针,建议使用它们我试图使用它们.

问题是,我不太确定在这种情况下使用它们的"最佳方式"是什么...阅读智能指针后:或者谁拥有你的宝贝?哪一种指针的我时使用?还有一些我得出了不同的结论:

第一种是使用a,*unique_ptr因为编辑的对象显然是创建并删除其子对象的所有者.小部件只是指孩子显示或更改它们.问题是小部件应该如何引用孩子......

现在我只是仍然使用我用get()方法获得的原始指针,unique_ptr但这对我来说似乎有点瑕疵.我仍然可以意外调用指针上的删除并取消智能指针的好处.

第二种方法是使用a,shared_ptr因为许多对象引用子进程并对其进行编辑.在一个小部件中意外删除它也不会有害,因为它仍归其他对象所有.问题是他们拥有它.当我想从编辑过的对象中删除它时,我还必须发信号通知所有小部件,以便在它真正消失之前将其删除.(这似乎又有缺陷且容易出错)

我对两种方式都不满意.是否有一种干净的(呃)方式指向unique_ptr对象的孩子?或者我错过了一个完全不同的更好的方法来解决这个问题?

c++ pointers reference unique-ptr

7
推荐指数
1
解决办法
2830
查看次数

既然存在智能指针,那么使用C类型指针的方式是否已弃用?

可能重复:
我使用哪种指针?

有许多专业人士赞成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的回答:

使用哑指针(原始指针)或对资源的非拥有引用的引用,当>你知道资源将比引用对象/范围更长时.当您需要可空性或可重置性时,首选引用和>使用原始指针.

如果这就是全部,我接受这个问题已被关闭.

c++ smart-pointers c++11

6
推荐指数
2
解决办法
1273
查看次数

使用裸指针而不是weak_ptr 有什么好处吗?

问题:是否有任何令人信服的理由将裸指针用于非拥有资源,或者我们应该使用weak_ptr

CPP.参考状态

std::weak_ptr 模型临时所有权:当对象只有存在时才需要访问,并且可以随时被其他人删除

但是,在接受的答案中,我何时使用哪种指针?我们有以下声明:

对资源的非拥有引用使用哑指针(原始指针)或引用,并且当您知道资源将超过引用对象/范围时。当您需要可空性或可重置性时,更喜欢引用并使用原始指针.... ashared_ptr并使用 a weak_ptr

这个答案后面有很多关于使用裸指针的反复讨论,没有真正的解决方案。我看不出使用哑指针的任何理由。我错过了什么吗?

c++ pointers smart-pointers c++11

4
推荐指数
1
解决办法
2382
查看次数

谁负责删除?

我正在分析代码,我对特定代码感到困惑.我发布了代码/伪代码,它们将传达相同的含义.

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++ dynamic delete-operator

3
推荐指数
1
解决办法
549
查看次数

什么是C ++中的原始指针?它们与普通指针有何不同?

原始指针有什么特殊含义吗?

普通指针变量和原始指针是否相同?

c++ pointers

3
推荐指数
2
解决办法
1万
查看次数