Как я могу сказать компилятору не создавать временный объект? - PullRequest
7 голосов
/ 06 февраля 2009

Я изменяю старую подпрограмму, которая раньше принимала целочисленный параметр, так что теперь она принимает константную ссылку на объект. Я надеялся, что компилятор скажет мне, откуда вызывается функция (потому что тип параметра неверен), но у объекта есть конструктор, который принимает целое число, поэтому вместо сбоя компилятор создает временный объект и передает ему целое число и передает ссылку на это в процедуру. Пример кода:

class thing {
  public:
    thing( int x ) {
        printf( "Creating a thing(%d)\n", x );
    }
};

class X {
  public:
    X( const thing &t ) {
        printf( "Creating an X from a thing\n" );
    }
};


int main( int, char ** ) {
    thing a_thing( 5 );
    X an_x( 6 );
    return 1;
}

Я хочу, чтобы строка X an_x( 6 ) в не компилировалась , потому что не существует X конструктора, который принимает int. Но он компилируется, и вывод выглядит так:

Creating a thing(5)
Creating a thing(6)
Creating an X from a thing

Как сохранить конструктор thing( int ), но запретить временный объект?

Ответы [ 2 ]

11 голосов
/ 06 февраля 2009

Используйте ключевое слово explicit в конструкторе вещей.

class thing {
public:
    explicit thing( int x ) {
        printf( "Creating a thing(%d)\n", x );
    }
};

Это предотвратит неявный вызов компилятором конструктора вещи, когда он найдет целое число.

1 голос
/ 06 февраля 2009

Ключевое слово explicit отлично работает в моем примере, но позже я понял, что мой код реального мира не работает на перегруженном методе, а не на конструкторе. (Я виноват в том, что задал вопрос, который был похож на мою настоящую проблему, но не совпадал с ней.) Как отметил Марк Рэнсом в комментариях к принятому ответу, explicit работает только на конструкторах. Я нашел обходной путь, который решил мою проблему, поэтому я решил опубликовать его здесь. Новый пример кода:

class thing {
  public:
    thing( int x ) {
        printf( "Creating a thing(%d)\n", x );
    }
};

class X {
  public:
    void do_something( const thing &t ) {
        printf( "Creating an X from a thing\n" );
    }
};


int main( int, char ** ) {
    thing a_thing( 5 );
    X an_x;
    an_x.do_something( 6 );
    return 1;
}

Этот код показывает тот же вывод, что и исходный код, но я не могу использовать explicit, чтобы исправить это. Вместо этого я добавил приватный метод, который принимает int:

  private:
    void do_something( int x );

Теперь компилятор не создает временный объект, он выдает ошибку, потому что я пытаюсь вызвать закрытый метод извне класса.

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