2015-04-10 3 views
-2

Я писал код для учебного упражнения и столкнулся с простым вопросом. Было бы лучше, если бы я показал примеры в первую очередь.C++ Класс Состав: Конструктор? или()?

  • Первый класс: FCLASS heaader

    class fClass 
    { 
    public: 
        explicit fClass(int = 0, int = 0); 
        fClass& operator()(int, int); 
        void print(); 
    private: 
        int x; 
        int y; 
    } 
    
  • Первый класс: FCLASS каст

    fClass::fClass(int a, int b) 
    : x(a), y(b) 
    { 
    } 
    fClass& fClass::operator()(int a, int b) 
    { 
        x = a; 
        y = b; 
    } 
    void fClass::print() 
    { 
        cout << "x: " << x << "\ny: " << y << endl; 
    } 
    
  • Второй класс, sClass.h

    class sClass 
    { 
    public: 
        explicit sClass(int = 0, int = 0); 
        void print(); 
    private: 
        fClass firstClass; 
    } 
    
  • Второй класс, sClass.cpp

    sClass::sClass(int a, int b) 
    : firstClass(a, b) 
    { 
    } 
    void sClass::print() 
    { 
        firstClass.print(); 
    } 
    
  • Основная функция

    int main() 
    { 
        sClass secondClass(1, 2); 
        secondClass.print(); 
    } 
    

Теперь мой вопрос, когда я удалил функции оператора() в FCLASS. Код все еще работал! Насколько я понимаю, «явное» объявление конструктора fClass должно запрещать определение fClass sClass в его конструкторе (firstClass (a, b)), поскольку fClass уже явно определен в объявлении частного члена. Поэтому, чтобы повторно инициализировать его в sClass как firstClass (a, b), должна быть определена операторная функция() (как и я). Почему этот код работает без определения operator()?

Чтобы добавить дополнительные комментарии к моему вопросу, к моему пониманию, выражение 'firstClass (a, b)' не должно вызывать явный конструктор fClass, потому что он не первый раз инициализируется. Опять же, к моему пониманию, конструкторы вызываются, когда класс сначала инициализируется для построения класса. firstClass уже инициализирован и сконструирован в файле заголовка ...

+0

Только для вашей информации «класс» при определении экземпляров 'class sClass secondClass (1,2)' избыточен, аналогично для 'enum',' union', 'struct'. Тогда ни один из них не требует пяти файлов. При извлечении примера попробуйте поместить все в один файл и включить его, если это возможно. –

ответ

0

Вы смущены насчет ключевого слова explicit и operator().

Ключевое слово explicit препятствует вызову конструктора для неявного создания объекта.Простой пример:

Допустим, есть функция:

void foo(fClass obj) {...} 

Безexplicit ключевых слов, вы будете иметь возможность вызвать функцию, используя синтаксис:

foo({1, 2}); 

arugment {1,2} будет использоваться для вызова конструктора, и результирующий объект будет передан в foo.

С ключевое слово explicit, вы не сможете использовать это. Вы должны будете использовать:

foo(fClass{1, 2}); 

или

foo(fClass(1, 2)); 

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

fClass obj(1, 2); 
obj(10, 20); 

Вы сказали:

Как я понимаю explicit декларацию fClass 'конструктор s должен запретить sClass' s fClass определение в его конструктор (firstClass(a, b)), потому что fClass был явно определен в объявлении частного участника.

Не правильное понимание.

Линия

fClass firstClass; 

в определении класса sClass просто говорит о том, что класс имеет переменную-член с именем firstClass и его тип fClass. Он не устанавливает значение переменной при создании объекта sClass.

В определении конструктора sClass вы инициализируете элемент, используя : firstClass(a, b), что и нужно делать. Если вы его пропустите, элемент будет инициализирован так, как если бы вы использовали :firstClass(), что является допустимым способом инициализации объекта типа fClass.

+0

@R Sahu: Большое вам спасибо за ваше объяснение. Теперь у меня есть лучшее понимание в явной и явной форме. Я думаю, что ваш ответ также отвечает на мой вопрос в комментарии Мэтта Макнабба: «Так значит ли это, что класс может быть повторно инициализирован даже после его объявления? Это означает, что после того, как я сделаю« sClass secondClass »; то я могу сделать «secondClass (int 1, int 2)»; в main()? Или это применяется только при инициализации, например, sClass :: sClass (int a, int b): firstClass (a, b) '? " Таким образом, это не будет разрешено за пределами конструктора sClass. Я прав? – GrinNare

+0

Нет, вы не можете использовать 'secondClass (int 1, int 2);' в 'main' или где-либо еще. Это утверждение неверно для нескольких учетных записей. –

0

Ключевое слово explicit предотвращает случаи, когда объект может быть преобразован путем передачи его функции. Твой не такой случай. Я не знаю, где эта перегрузка operator() должна иметь какое-либо влияние, может быть, если вы указали URL-адрес на текст, который утверждал это, люди здесь могли бы расшифровать реальный смысл (или его отсутствие) для вас.

2

Код:

sClass::sClass(int a, int b) 
    : firstClass(a, b) 

означает, что firstClass субобъект будет иметь конструктор с именем, который принимает a и b. Для этого используются конструкторы explicit, а operator() не имеет отношения.

Ваш код не вызывает operator() в любом месте, поэтому неудивительно, что удаление этого не имеет значения. Этот оператор используется, когда имя переменной используется в выражении, за которым следуют скобки.

+0

@ Мэтт Макнабб: Спасибо за объяснение. Значит ли это, что класс может быть повторно инициализирован даже после его объявления? значение после того, как я сделаю «sClass secondClass»; то я могу сделать «secondClass (int 1, int 2);»? Или это применимо только при инициализации, например, sClass :: sClass (int a, int b): firstClass (a, b) '? – GrinNare

+0

Конструкторы классов @GrinNare можно вызывать только один раз на объект, в точке построения. 'secondClass (1, 2);' вызывает оператор '()'. –

+0

@ Matt McNabb: Большое вам спасибо за ваши ответы. Очень грустно, что я могу выбрать только один ответ. Обучение без учителя или профессора чрезвычайно затруднено ... (Еще раз спасибо. – GrinNare

Смежные вопросы