1

我已经定义了一个成员变量,如下所示。由于变量不会被传递,所以我决定在这里使用 scoped_ptr 而不是 shared_ptr。

class ClassName
{
public:
    ClassName() 
    {
        Initialize();
    }

    virtual void Initialize() = 0;

protected:
    boost::scoped_ptr<int> m_scpInt;
}

class ClassNameB : public ClassName
{
public:
    virtual void Initialize()
    {
        m_scpInt.reset(new int(100));
    }
}

由于 scoped_ptr 的限制,如果我决定稍后推迟初始化变量,我得到的唯一选择就是调用 reset。

Q1> 这是一个好习惯吗?

Q2>否则,有没有更好的解决方案?

谢谢

/// 更新 -1 ///

这是我真正想做的。

我想强制每个派生类定义一个名为 Initialize 的函数,然后该函数又调用函数 InitializeVarA 和 InitializeVarB。正如您所指出的,我们不能在构造函数中调用虚函数。

class ClassName
{
public:
    ClassName() 
    {
    }       
    virtual void Initialize()
        {
            InitializeVarA();
            InitializeVarB();
        }           
    protected:
        virtual void InitializeVarA() {}
        virtual void InitializeVarB() {}
}

class ClassNameB : public ClassName
{
public:
    ClassNameB() 
    {
    }       
    virtual void Initialize()
        {
            InitializeVarA();
            InitializeVarB();
        }           
    protected:
        virtual void InitializeVarA() {}
        virtual void InitializeVarB() {}
}

ClassNameB cb;
cb.Initialize();

我有比这更好的解决方案吗?

4

1 回答 1

4

这是一个好习惯吗?

使用reset重置作用域指针很好。

尝试通过从基类的构造函数调用虚函数来初始化派生类不仅是不好的做法。这是错的。此时,对象的动态类型是基类,而函数是纯虚拟的,因此调用它会产生未定义的行为。

即使你把它变成非纯的,你仍然不能在那个时候调用派生类的覆盖,所以指针不会被重置。

否则,有没有更好的解决方案?

您可以在派生类的构造函数中执行此操作,该构造函数在基类之后立即调用:

class Base {
public:
    Base() { /* don't call any virtual functions here */ }

protected:
    boost::scoped_ptr<int> p;
};

class Derived : public Base {
public:
    Derived() {
        p.reset(new int(100));
    }
};

或者您可以将分配的内存传递给基类构造函数并从中初始化指针。不过这有点危险——您必须确保在任何可能引发异常或内存泄漏之前立即初始化指针。

class Base {
public:
    Base(int * p) : p(p) {}

private: // doesn't need to be protected now
         // (unless something else in the derived class needs access)
    boost::scoped_ptr<int> p;
};

class Derived : public Base {
public:
    Derived() : Base(new int(100)) {}
};

在 C++11 中,您可以使用unique_ptr可移动的 来避免泄漏风险:

class Base {
public:
    typedef std::unique_ptr<int> ptr;
    Base(ptr && p) : p(p) {}

private:
    ptr p;
};

class Derived : public Base {
public:
    Derived() : Base(ptr(new int(100))) {}
};
于 2012-08-08T14:52:17.717 回答