Вопрос

Ранее я спрашивал, почему это считается плохим:

class Example
{
 public: 
  Example(void);
  ~Example(void);
  void f() {}
}

int main(void)
{
 Example ex(); // <<<<<< what is it called to call it like this?

 return(0);
}

Теперь я понимаю, что вместо этого создается прототип функции, который возвращает пример типа.Хотя я все еще не понимаю, почему это будет работать в g ++ и MS VC ++.

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

int main(void)
{
 Example *e = new Example();

 return(0);
}

?В чем разница между этим и простым вызовом Example e()???Как будто я знаю, что это прототип функции, но, похоже, возможно, некоторые компиляторы прощают это и позволяют ему вызывать конструктор по умолчанию?Я тоже это пробовал:

class Example
{
 private:
  Example();

 public:
  ~Example();
};

int main(void)
{
 Example e1(); // this works
 Example *e1 = new Example(); // this doesn't

 return(0);
}

Так что я немного сбит с толку: ( Извините, если об этом спрашивали миллион раз.

Это было полезно?

Решение

это вопрос будет полезно понять это поведение

Другие советы

Это просто, Дэниел:

Example *e = new Example();

Это не похоже на функцию под названием "Example", не так ли?Функция имеет возвращаемое значение, имя и параметры.Как бы к этому подошло вышесказанное?

Пример e1();// это работает

Да, потому что вы не создаете никакого экземпляра Example где угодно.Вы просто сообщаете коду, что где-то в окружающем пространстве имен есть функция, определенная, и вы, возможно, хотите вызвать эту функцию.Да, это правда, что для того, чтобы вернуть объект Example, должен быть создан экземпляр.Но это не означает, что в этот момент создается экземпляр.Скорее, экземпляр создается в функции, когда вы ее вызываете.

Хм...Хорошо, это:

Пример e1();

Не работает.Вы можете подумать, что это так, или какой-то компилятор принимает это, но он не создает экземпляр Example с именем e1, он просто объявляет прототип функции.Снимите скобки, и он сделает то, что вы хотите.

Это:

Пример * e1 = новый пример();

Не будет работать, потому что конструктор является закрытым.Если вы сделаете конструктор общедоступным, он создаст объект в куче, и e1 будет указателем на этот объект.Вам нужно будет удалить объект, когда вы закончите с ним.

Для первого вопроса о том, будет ли "новый пример ()" действительным.Да, это совершенно легальный код на C ++.Хотя, чтобы быть полностью корректным, вам нужно будет удалить объект перед возвратом из main(), иначе это приведет к утечке памяти.

Пример:

int main(void)
{
 Example *e = new Example();
 delete e;
 return(0);
}

Что касается последнего вопроса.Строка "Example e1();" является допустимой, поскольку в ней объявляется прототип функции.На самом деле это не приводит к выполнению машинного кода (ну, может быть, пространство стека).Это просто говорит о том, что существует прототип функции без аргументов, возвращающий тип Example .

Однако вторая строка определенно потерпит неудачу.На этом этапе вы пытаетесь фактически выполнить конструктор, например.Это незаконно, поскольку доступность функции является частной, отсюда и ошибка компилятора.

Я думаю, вам следует различать "это анализирует", "это компилирует", "это связывает" и "это работает", и попробуйте сами мыслить как синтаксический анализатор / компилятор / компоновщик C ++, чтобы увидеть, что первый пример

Example e1(); // function prototype

выглядит как объявление функции.Синтаксический анализатор будет поймите это таким образом, поэтому вы не можете вызвать, напримерфункция - член на e1.Компилятор сгенерирует символ, ссылающийся на некоторую функцию (он пока не видит), но поскольку функция нигде не используется, он не будет жаловаться.Если вы добавите этот код, он будет:

e1.f();// since e1 is a function, it has no member 'f' => compiler error

( в качестве примечания:этот код также будет скомпилирован:

int a_function_prototype(int); // another prototype.
e1(); // should work!
a_function_prototype(5);

но после того, как компилятор завершит работу, компоновщик начнет искать фактические тела функций и не найдет ни одного.)

Теперь , поскольку линия

Example* e = new Example();

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top