2015-10-01 3 views
-1

Я пытаюсь понять, что такое конструктор, и не могли бы вы рассказать мне, почему я все еще могу запустить программу без ошибок?проблема с пониманием конструктора

Как вы можете видеть, я делаю это неправильно, но это все еще работает !! Зачем?? и когда я попытался поместить LL = (имя объекта) после моего класса DELL, он не работает? но когда я получил LL, он работает почему ??? Если я не ясно, не стесняйтесь сказать мне и я извиняюсь заранее за этот беспорядок

#include <iostream> 
#include <string> 
using namespace std; 


class DELL{ 
public: 
    DELL(){ 
     cout <<" bla bl bla\n"; 
    } 
    void setname(string x){ 
     name = x; 
} 

     string getname() 
     { 
      return name;} 
private: 
string name; 


}; 

int main(){ 

    DELL(); // Variant 1 
    DELL LL(); // Variant 2 
    return 0; 

} 
+0

Почему у вас есть две функции 'main'? И когда вы говорите: «Я не делаю это правильно», что такое «это» и как вы не делаете это правильно? – interjay

+1

'DELL LL();' - объявление функции. – MikeCAT

+0

'DELL();' делает аномальный объект класса 'DELL'. – MikeCAT

ответ

0

Вы прервали причуду грамматики C++, известная как досадно разбор. Короче говоря:

DELL LL(); 

объявляет функцию с именем LL, которая не имеет параметров и возвращает объект DELL. Сравните синтаксис DELL LL(); и int main();.

Этот код:

DELL(); 

создает временный объект типа DELL и инициализирует его с помощью конструктора по умолчанию.

Этот код:

DELL LL; 

создает объект с именем LL, типа DELL, и по умолчанию-инициализирует его. Для класса это означает вызов конструктора по умолчанию.

Начиная с C++ 11, вы можете использовать фигурные скобки вместо круглых скобки для инициализации, что позволяет избежать неприятных разобрано:

DELL LL{}; 

Это создает объект LL, типа DELL и ценностные инициализирует IT , Для класса это снова означает вызов конструктора по умолчанию.

+0

Может быть, изменить «Vexing Parse», чтобы ссылаться на это - https://en.wikipedia.org/wiki/Most_vexing_parse? – borisbn

+0

@borisbn Вещь - это не самый неприятный парсис; это будет 'T t (T());'. Это просто анализ Vexing, 'T t();'. – Angew

+0

Большое спасибо всем вам за эти знания. Надеюсь, однажды я вам тоже помогу! – Juststarted26092015

0

Вы не делаете это неправильно. Вы просто не делаете это «правильно».

Вы объявляете класс с именем DELL и имеет только один конструктор, который не требует дополнительных параметров.

public: 
    DELL(){ 
     cout <<" bla bl bla\n"; 
    } 

Теперь в вашем main() вы называете этот конструктор, но не создать объект класса DELL;

Правильный способ создания объекта DELL будет:

DELL LL; 
//and then you could maybe do 
LL.setname("name of object"); 
cout<<LL.getname(); 

Когда вы запустите эту программу, вывод будет:

bla bla bla 
name of object 

Кроме того, вы можете создать указатель на объект DELL by>

int main(){ 

    DELL *ll; 
    ll = new DELL(); 

    ll->setname("name of object"); 
    cout<<ll->getname(); 

    return 0; 
} 

И выход будет таким же, как и выше.

+0

Кстати, я знаю, что вы не используете конструктор для такого рода ситуаций, но, с другой стороны, я думал, что конструктор из моего исследования был доброй специальной функцией, которая давала бы те же вещи, что и ваш второй пример. но это был не просто еще один способ быстрее написать код вместо использования ----------------------------------- ---------------------------------------------- DELL LL; LL.setname ("имя объекта"); cout << LL.getname(); но я думаю, что я ошибся и пропустил это видео https://www.youtube.com/watch?v=_b7odUc7lg0, но спасибо большое !!! – Juststarted26092015

+0

Я не уверен, что понимаю, что вы говорите ... Я думаю, вы хотите установить 'name' в конструкторе, и вы можете это сделать, но тогда вам нужен конструктор с параметром' string'. ..DELL (строка str) { name = str; } – Rorschach

+0

Я пытался сделать то же самое, что и в этом видео https: //www.youtube.com/watch? V = _b7odUc7lg0 ..... да, это часть 2 в видео, которую парень показывает еще один пример, используя ........................ класс buckysclass { общественность: \t buckysclass (строка z) { имя-набора (z); – Juststarted26092015

1

Прежде всего, давайте увеличим ваш класс DELL, чтобы добавить к нему деструктор. Это поможет нам лучше понять жизненный цикл вашего объекта. Вот код:

class DELL { 
public: 
    DELL() { 
     std::cout << "DELL constructor called\n"; 
    } 
    ~DELL() { 
     std::cout << "DELL destructor called\n"; 
    } 
}; 

Вот 3 возможные способы, которыми Вы можете играть с этим:

DELL(); - Это построить временный объект типа DELL(). Он удаляется сразу после этого, и поскольку он не используется, оптимизированные компиляторы могут просто полностью отказаться от этой строки. Однако, если вы отключите оптимизацию и компилируете/связываете/запускаете свой код, вы должны увидеть вызов конструктора, за которым сразу следует вызов деструктора. Пример кода ниже приведет к созданию конструктора, деструктора, распечаток контрольных точек в этом порядке.

DELL(); 
std::cout << "Checkpoint.\n"; 

DELL LL; это создает объект типа DELL. Этот объект будет жить до конца области, где он будет объявлен. Если вы поместите это в ваш главный, и чем выходной то после этого, как следующий

{ 
DELL LL; 
std::cout << "Checkpoint.\n"; 
} 

Вы увидите вызов конструктора, «Checkpoint» и чем деструктора вызов в качестве выхода (опять же, при условии, нет оптимизации не происходит) ,

DELL LL(); - это не создает объектов. Вместо этого он объявляет функцию с именем LL, которая не принимает аргументов и возвращает объект типа DELL. Когда вы запустите этот код, вы не увидите выхода из конструктора или деструктора, потому что объект не был создан.

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