3

假设我有一个不可复制的Foo,并且它的一个构造函数恰好接收到对Foo.

class Foo
{
public:
    Foo(Foo& parent) {...}

private:
    void operator=(Foo); // disabled
    ...
};

编译器认为这是一个复制构造函数,而它所做的事情与复制完全无关(因此赋值运算符被禁用)。

以这种方式定义构造函数是否有任何危险,或者我应该人为地更改它的签名,例如使用指针而不是引用,或者添加一个强制性的虚拟参数?

这是一些上下文(可能不需要理解/回答我的问题)。

我有一个自己编写的类库,用作用户代码和另一个库之间的连接。另一个库提供了一项服务,为简洁起见,我将其称为frobnicate。用户代码可能如下所示:

class UsefulObject: public mylib::Frobnicator
{
    ...
    void DoStuff()
    {
        int x = ...
        ...
        frobnicate(x); // it's important to allow simple syntax here
        frobnicate(x + 1);
        ...
    }
    ...
};

我想支持用户对象的层次结构:每个对象都包含在另一个对象(它的父对象)中,而有几个(在我的例子中是 5 个)包含所有其他对象的顶级对象。

每个对象都有一个日志文件;我希望每个调用都记录在几个日志文件中,沿着包含层次结构向上直到一个顶级对象。

我以这种方式实现了它:

namespace mylib
{
    class Frobnicator // provides the frobnication service
    {
    public:
        Frobnicator(Frobnicator& parent): parent(parent) {}
    protected:
        virtual void frobnicate(int x) {
            ... // some logging code
            parent->frobnicate(x);
        }
    private:
        Frobnicator& parent;
    };

    namespace internal // users of mylib, please don't use this!
    {
        class TheUltimateFrobnicator: public Frobnicator
        {
        protected:
            virtual void frobnicate(int x) {
                the_other_library::frobnicate(x);
            }
        private:
            TheUltimateFrobnicator(int id); // called by a factory or some such
        };
    }
}
4

1 回答 1

7

在这种构造函数的含义上,这似乎是一个不幸的歧义。我认为消除歧义的最直接方法是使用指针

class Frobnicator // provides the frobnication service
{
public:
    explicit Frobnicator(Frobnicator *parent): parent(parent) {}
protected:
    virtual void frobnicate(int x) {
        ... // some logging code
        parent->frobnicate(x);
    }
private:
    void operator=(Foo); // disabled
    Frobnicator(Frobnicator const&); // disabled

    Frobnicator *parent;
};

我知道很多人都希望参数是一个指针。顺便说一句,您自己输入错误parent.frobnicateparent->frobnicate.

于 2011-01-23T14:23:03.353 回答