Является ли следующий действительный код C ++? - PullRequest
1 голос
/ 04 февраля 2010

Если это так, что он должен делать?

typedef struct Foo_struct{
  Dog d;
  Cat* c;
  struct Foo_struct(Dog dog, Cat* cat){ this->d = dog; this->c = cat;}
} Foo;

(история вопроса: перенос программы, написанной на Visual C ++ (для Windows), на g ++ (на MacOSX), понятия не имею, что это за кодрекомендуется сделать).

Спасибо!

Ответы [ 5 ]

8 голосов
/ 04 февраля 2010

Не думаю, что это так. (И Comeau соглашается со мной.) Вы не можете определить конструктор, как это.

В C ++ имена структур являются первоклассными гражданами. Нет необходимости использовать старый трюк typedef из C. Кроме того, d и c должны быть инициализированы в списке инициализации члена. Это будет правильно (и лучше (C ++):

struct Foo {
  Dog d;
  Cat* c;
  Foo(Dog dog, Cat* cat) : d(dog), c(cat) {}
};

Код определяет структуру (в C ++, такую ​​же, как класс, за исключением того, что ее члены по умолчанию являются открытыми) с конструктором для инициализации его членов при создании.

Редактировать: Как сказал Тревис в своем комментарии, вы можете рассмотреть возможность передачи dog в качестве ссылки const вместо ее копирования:

Foo(const Dog& dog, Cat* cat) : d(dog), c(cat) {}

Если Dog (которого мы не видели) - это класс с более чем одним встроенным членом, это может быть значительно дешевле, чем передавать его за копию.

5 голосов
/ 04 февраля 2010

Нет, это не так.Вы не можете иметь struct в конструкторе.Действительный код C ++ с минимальным изменением будет

typedef struct Foo_struct{
  Dog d;
  Cat* c;
  Foo_struct(Dog dog, Cat* cat){ this->d = dog; this->c = cat;}  // <-- remove the "struct"
} Foo;

. Для лучшего подхода смотрите ответ @ sbi.

4 голосов
/ 04 февраля 2010

В основном, хотя struct и typedef не нужны.Лучше написано на C ++ как:

class Foo {
  public:
    Foo(Dog dog, Cat *cat) : d(dog), c(cat) {}
  private:
    Dog d;
    Cat *c;
};

Строка за строкой:

class Foo {

То же, что struct Foo.Единственное отличие в C ++ между class и struct состоит в том, что члены struct являются открытыми по умолчанию, а члены class являются частными.Но нам нужны где-то открытые члены, поэтому мы можем обойти это с помощью ...

  public:

Все, что после этого, является публичным, и любой может получить доступ к нему с Foo объектом.*

Это конструктор для Foo.Создается новый объект Foo с Dog и Cat *.: d(dog), c(cat) является списком инициализаторов.Это то же самое, что и this->d = dog; this->c = cat;, за исключением, вероятно, быстрее.Если вы не хотите делать это таким образом, вы можете пропустить this->, если где-то не возникнет конфликт имен.{} - это тело функции, пустое, потому что мы переместили назначение в список инициализатора.

  private:

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

    Dog d;
    Cat *c;

Это внутренние переменные класса, например члены struct.

3 голосов
/ 04 февраля 2010

Это почти законно, но есть одна ошибка. Структура похожа на класс, за исключением того, что защита по умолчанию - public, а не private.

Хорошо, давайте разберемся:

// The next line is defining a struct called "Foo_struct", it's also
// saying it's going to give an alternate type name (that's the typedef).
// The alternate type name comes after the definition.
typedef struct Foo_struct{

  // The structure has a Dog element (this means we need to have seen
  // the definition of Dog already).
  Dog d;

  // And has a pointer to cat (this means we need to have at least seen
  // a declaration of Cat) 
  Cat* c;

  // Okay, this is definining a constructor.  The constructor must be
  // called with a Dog object and a pointer to a cat which the constructor
  // will save in the object.
  //
  // Here is the one error.  That 'struct' at the start shouldn't
  // be there (commenting out to make the code legal).
  /* struct */ Foo_struct(Dog dog, Cat* cat){ this->d = dog; this->c = cat;}

// And here we close out the struct and also finish off the typedef
// started on the first line.
} Foo;
0 голосов
/ 04 февраля 2010

Похоже, что он определяет структуру с именем Foo_Struct, которая содержит экземпляр Dog, имеет указатель на cat и имеет конструктор, который принимает экземпляр Dog, указывает на Cat и присваивает их себе.

Затем создает экземпляр Foo в стеке.

Редактировать: Я не уверен, является ли эта третья строка конструктором или чем-то еще.

...