C++ - конструкция объекта в классе

Просто отфильтруйте столбцы из фрейма данных «resultb2», а затем добавьте. Нравится:

resultb1 = resultb1.append(resultb2[["column1","column2","column3",......]])
print(resultb1)
24
задан SolarBear 11 May 2009 в 21:22
поделиться

8 ответов

Он будет инициализирован конструктором по умолчанию. Если вы хотите использовать другой конструктор, у вас может получиться что-то вроде этого:

class Foo
{
    public: 
    Foo(int val) { }
    //stuff
};

class Bar
{
    public:
    Bar() : foo(2) { }

    Foo foo;
};
24
ответ дан 28 November 2019 в 23:04
поделиться

Если вы явно не вызываете конструктор foo внутри конструктора Bar, то будет использоваться конструктор по умолчанию. Вы можете контролировать это, явно вызывая конструктор

Bar::Bar() : foo(42) {}

. Конечно, предполагается, что вы добавили в код Foo :: Foo (int) :)

3
ответ дан 28 November 2019 в 23:04
поделиться

Вам не нужно явно вызывать конструктор по умолчанию в C ++, он будет вызван за вас. Если вы хотите вызвать другого конструктора, вы можете сделать это:

Foo foo(somearg)
0
ответ дан 28 November 2019 в 23:04
поделиться

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

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

class Foo {
public:
    Foo(int x) { .... }
};

class Bar {
public:
    Bar() : foo(42) {}

    Foo foo;
};

Но если бы у Foo был конструктор по умолчанию Foo (), компилятор автоматически сгенерирует конструктор Bar, и это вызовет Foo по умолчанию (т.е. Foo ( ))

1
ответ дан 28 November 2019 в 23:04
поделиться

Если не указано иное, foo инициализируется с использованием конструктора по умолчанию. Если вы хотите использовать какой-то другой конструктор, вам нужно сделать это в списке инициализаторов для Bar:

Bar::Bar( int baz ) : foo( baz )
{
    // Rest of the code for Bar::Bar( int ) goes here...
}
1
ответ дан 28 November 2019 в 23:04
поделиться

Есть четыре функции, которые компилятор C ++ сгенерирует для каждого класса, если он может и если вы их не предоставите: конструктор по умолчанию, конструктор копирования, оператор присваивания и деструктор. В стандарте C ++ (глава 12, «Специальные функции») они называются «неявно объявленными» и «неявно определенными». У них будет общий доступ.

Не путайте «неявно определенные» с «по умолчанию» в конструкторе. Конструктор по умолчанию - это тот, который можно вызвать без аргументов, если он есть. Если вы не предоставите конструктор, значение по умолчанию будет определено неявно. Он будет использовать конструкторы по умолчанию для каждого базового класса и члена данных.

Итак, происходит то, что класс Foo имеет неявно определенный конструктор по умолчанию, а Bar (который, похоже, не имеет определяемого пользователем конструктора) использует его неявно определенный конструктор по умолчанию, который вызывает конструктор по умолчанию Foo.

Если вы действительно хотите написать конструктор для Bar, вы можете упомянуть foo в его списке инициализаторов, но поскольку вы используете конструктор по умолчанию, вам на самом деле не нужно укажите его.

Помните, что если вы напишете конструктор для Foo, компилятор не сгенерирует автоматически конструктор по умолчанию, поэтому вам придется указать его, если он вам нужен. Следовательно, если бы вы поместили что-то вроде Foo (int n); в определение Foo, а не t явно написать конструктор по умолчанию (либо Foo (); , либо Foo (int n = 0); ), у вас не может быть Bar в его нынешнем виде, поскольку он не может не использовать конструктор по умолчанию Foo. В этом случае вам понадобится конструктор типа Bar (int n = 0): foo (n) {} , в котором конструктор Bar инициализирует Foo. (Обратите внимание, что Bar (int n = 0) {foo = n;} или что-то подобное не сработает, поскольку конструктор Bar сначала попытается инициализировать foo, и это не удастся.)

foo (n) {} , когда конструктор Bar инициализирует Foo. (Обратите внимание, что Bar (int n = 0) {foo = n;} или что-то подобное не сработает, поскольку конструктор Bar сначала попытается инициализировать foo, и это не удастся.)

foo (n) {} , когда конструктор Bar инициализирует Foo. (Обратите внимание, что Bar (int n = 0) {foo = n;} или что-то подобное не сработает, поскольку конструктор Bar сначала попытается инициализировать foo, и это не удастся.)

6
ответ дан 28 November 2019 в 23:04
поделиться

Итак, Bar содержит полный объект Foo, а не только ссылку или указатель. Инициализируется ли этот объект конструктором по умолчанию?

Если Foo имеет ctor по умолчанию, объект типа Foo будет использовать ctor по умолчанию при создании объекта типа Бар . В противном случае вам нужно вызвать Foo ctor самостоятельно, иначе ваш компилятор Bar заставит ваш компилятор долго жаловаться.

Например:

class Foo {
public:
 Foo(double x) {}
};

class Bar  {
 Foo x;
};

int main() {
 Bar b;
}

Вышеупомянутое вызовет жалобу компилятора что-то вроде:

«В конструкторе 'Bar :: Bar ()': Строка 5: ошибка: нет соответствующей функции для вызова 'Foo :: Foo ()'

Нужно ли мне явно вызывать его конструктор, и если да, то как и где?

Измените приведенный выше пример следующим образом:

class Foo {
 public:
  Foo(double x) {} // non-trivial ctor
};

class Bar  {     
 Foo x;
public:
  Bar() : x(42.0) {} // non-default ctor, so public access specifier required
};

int main() {
 Bar b;
}
1
ответ дан 28 November 2019 в 23:04
поделиться

Построение - довольно сложная тема в C ++. Простой ответ: это зависит . Инициализируется ли Foo или нет, зависит от определения самого Foo. По поводу второго вопроса: как заставить Bar инициализировать Foo: списки инициализации являются ответом.

Хотя общее мнение таково, что Foo будет инициализироваться по умолчанию неявным конструктором по умолчанию (сгенерированным компилятором), который не нужно придерживаться правды.

Если Foo не имеет определяемого пользователем конструктора по умолчанию, то Foo будет неинициализирован. Чтобы быть более точным: каждый член Bar или Foo, у которого отсутствует определяемый пользователем конструктор по умолчанию, будет неинициализирован сгенерированным компилятором конструктором по умолчанию для Bar :

class Foo {
   int x;
public:
   void dump() { std::cout << x << std::endl; }
   void set() { x = 5; }
};
class Bar {
   Foo x;
public:
   void dump() { x.dump(); }
   void set() { x.set(); } 
};
class Bar2
{
   Foo x;
public:
   Bar2() : Foo() {}
   void dump() { x.dump(); }
   void set() { x.set(); }
};
template <typename T>
void test_internal() {
   T x;
   x.dump();
   x.set();
   x.dump();
}
template <typename T>
void test() {
   test_internal<T>();
   test_internal<T>();
}
int main()
{
   test<Foo>(); // prints ??, 5, 5, 5, where ?? is a random number, possibly 0
   test<Bar>(); // prints ??, 5, 5, 5
   test<Bar2>(); // prints 0, 5, 0, 5
}

Теперь, если бы Foo имел конструктор, определенный пользователем, он бы инициализироваться всегда, независимо от того, есть ли у Bar конструктор, инициализированный пользователем. Если у Bar есть определяемый пользователем конструктор, который явно вызывает (возможно, неявно определенный) конструктор Foo, то Foo фактически будет инициализирован. Если список инициализации Bar не вызывает конструктор Foo, он будет эквивалентен случаю, когда Bar не имеет конструктора, определенного пользователем.

Тестовый код может потребовать некоторых пояснений. Нас интересует, действительно ли компилятор инициализирует переменную без фактического вызова конструктора пользовательским кодом. Мы хотим проверить, инициализирован ли объект или нет. Теперь, если мы просто создадим объект в функции, он может попасть в позицию памяти, которая не была затронута и уже содержала нули. Мы хотим отличить удачу от успеха, поэтому мы определяем переменную в функции и дважды вызываем ее. При первом запуске он распечатает содержимое памяти и принудительно внесет изменения. Во втором вызове функции, поскольку трассировка стека такая же, переменная будет сохранена в точно такой же позиции памяти. Если бы он был инициализирован, ему было бы присвоено значение 0, иначе оно сохранит то же значение, что и старая переменная, в той же самой позиции.

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

он распечатает содержимое памяти и принудительно внесет изменения. Во втором вызове функции, поскольку трассировка стека такая же, переменная будет сохранена в точно такой же позиции памяти. Если бы он был инициализирован, ему было бы присвоено значение 0, иначе оно сохранит то же значение, что и старая переменная, в той же самой позиции.

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

он распечатает содержимое памяти и принудительно внесет изменения. Во втором вызове функции, поскольку трассировка стека такая же, переменная будет сохранена в точно такой же позиции памяти. Если бы он был инициализирован, ему было бы присвоено значение 0, иначе оно сохранит то же значение, что и старая переменная, в той же самой позиции.

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

Во втором вызове функции, поскольку трассировка стека такая же, переменная будет сохранена в точно такой же позиции памяти. Если бы он был инициализирован, ему было бы присвоено значение 0, иначе оно сохранит то же значение, что и старая переменная, в той же самой позиции.

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

Во втором вызове функции, поскольку трассировка стека такая же, переменная будет сохранена в точно такой же позиции памяти. Если бы он был инициализирован, ему было бы присвоено значение 0, иначе оно сохранит то же значение, что и старая переменная, в той же самой позиции.

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

переменная будет храниться в той же самой позиции памяти. Если бы он был инициализирован, ему было бы присвоено значение 0, иначе оно сохранит то же значение, что и старая переменная, в той же самой позиции.

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

переменная будет храниться в той же самой позиции памяти. Если бы он был инициализирован, ему было бы присвоено значение 0, иначе оно сохранит то же значение, что и старая переменная, в той же самой позиции.

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

В каждом из запусков теста первое выводимое значение - это инициализированное значение (если оно действительно было инициализировано) или значение в этой позиции памяти, которое в некоторых случаях оказывается равным 0. Второе значение - это просто тестовый токен. представляет значение в ячейке памяти после его изменения вручную. Третье значение поступает из второго запуска функции. Если инициализируется переменная, она вернется к 0. Если объект не инициализирован, его память сохранит старое содержимое.

В каждом из запусков теста первое выводимое значение - это инициализированное значение (если оно действительно было инициализировано) или значение в этой позиции памяти, которое в некоторых случаях оказывается равным 0. Второе значение - это просто тестовый токен. представляет значение в ячейке памяти после его изменения вручную. Третье значение поступает из второго запуска функции. Если инициализируется переменная, она вернется к 0. Если объект не инициализирован, его память сохранит старое содержимое.

16
ответ дан 28 November 2019 в 23:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: