如何在构造函数中处理“this”指针? [英] How to handle 'this' pointer in constructor?

查看:173
本文介绍了如何在构造函数中处理“this”指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有对象在其构造函数中创建其他子对象,传递this,所以子对象可以将指针保存到其父对象。我在我的编程中广泛使用boost :: shared_ptr作为一个更安全的替代std :: auto_ptr或原始指针。所以孩子会有 shared_ptr< Parent> 的代码,boost提供 shared_from_this() 方法。



我的问题是 shared_from_this()不能在构造函数中使用,这不是真正的罪行,因为'this'不应该



Google的C ++样式指南状态构造函数应该只将成员变量设置为其初始值。任何复杂的初始化都应该在一个显式的Init()方法中。这解决了'this-in-constructor'问题以及其他几个问题。



我很烦的是,现在使用你的代码的人必须记得调用Init ()每次他们构造你的对象之一。我可以想到的唯一的办法是强制执行这一操作是通过断言Init()已经在每个成员函数的顶部被调用,但是这是繁琐的写和繁琐的执行。



有没有任何成语在任何步骤解决这个问题?

解决方案

使用工厂方法进行2阶段构建&初始化你的类,然后让ctor& Init()函数private。然后没有办法不正确地创建你的对象。只要记住保持析构函数的公开和使用智能指针:

  #include< memory> 

class BigObject
{
public:
static std :: tr1 :: shared_ptr< BigObject> Create(int someParam)
{
std :: tr1 :: shared_ptr< BigObject> ret(new BigObject(someParam));
ret-> Init();
return ret;
}

private:
bool Init()
{
//执行某些操作
return true;
}

BigObject(int para)
{
}

BigObject(){}

} ;


int main()
{
std :: tr1 :: shared_ptr< BigObject> obj = BigObject :: Create(42);
return 0;
}

EDIT: b

如果你想反对在栈上生活,你可以使用上述模式的变体。这样写将创建一个临时的,并使用复制ctor:

  #include< memory> 

class StackObject
{
public:
StackObject(const StackObject& rhs)
:n_(rhs.n_)
{
}

static StackObject Create(int val)
{
StackObject ret(val);
ret.Init();
return ret;
}
private:
int n_;
StackObject(int n = 0):n_(n){};
bool Init(){return true; }
};

int main()
{
StackObject sObj = StackObject :: Create(42);
return 0;
}


I have objects which create other child objects within their constructors, passing 'this' so the child can save a pointer back to its parent. I use boost::shared_ptr extensively in my programming as a safer alternative to std::auto_ptr or raw pointers. So the child would have code such as shared_ptr<Parent>, and boost provides the shared_from_this() method which the parent can give to the child.

My problem is that shared_from_this() cannot be used in a constructor, which isn't really a crime because 'this' should not be used in a constructor anyways unless you know what you're doing and don't mind the limitations.

Google's C++ Style Guide states that constructors should merely set member variables to their initial values. Any complex initialization should go in an explicit Init() method. This solves the 'this-in-constructor' problem as well as a few others as well.

What bothers me is that people using your code now must remember to call Init() every time they construct one of your objects. The only way I can think of to enforce this is by having an assertion that Init() has already been called at the top of every member function, but this is tedious to write and cumbersome to execute.

Are there any idioms out there that solve this problem at any step along the way?

解决方案

Use a factory method to 2-phase construct & initialize your class, and then make the ctor & Init() function private. Then there's no way to create your object incorrectly. Just remember to keep the destructor public and to use a smart pointer:

#include <memory>

class BigObject
{
public:
    static std::tr1::shared_ptr<BigObject> Create(int someParam)
    {
        std::tr1::shared_ptr<BigObject> ret(new BigObject(someParam));
        ret->Init();
        return ret;
    }

private:
    bool Init()
    {
        // do something to init
        return true;
    }

    BigObject(int para)
    {
    }

    BigObject() {}

};


int main()
{
    std::tr1::shared_ptr<BigObject> obj = BigObject::Create(42);
    return 0;
}

EDIT:

If you want to object to live on the stack, you can use a variant of the above pattern. As written this will create a temporary and use the copy ctor:

#include <memory>

class StackObject
{
public:
    StackObject(const StackObject& rhs)
        : n_(rhs.n_)
    {
    }

    static StackObject Create(int val)
    {
        StackObject ret(val);
        ret.Init();
        return ret;
    }
private:
    int n_;
    StackObject(int n = 0) : n_(n) {};
    bool Init() { return true; }
};

int main()
{
    StackObject sObj = StackObject::Create(42);
    return 0;
}

这篇关于如何在构造函数中处理“this”指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆