Конструктор Foo :: Foo получает ссылку на Foo, но не копирует конструктор - PullRequest
3 голосов
/ 23 января 2011

Предположим, у меня есть не копируемый класс 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
        };
    }
}

1 Ответ

7 голосов
/ 23 января 2011

Кажется, это неудачная двусмысленность в значении такого конструктора.Я думаю, что самый простой способ устранить эту неоднозначность - это использовать указатель

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.frobnicate как parent->frobnicate.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...