Перегрузка конструктора в С++
Перегрузка My С++ не действует так, как я предполагаю:
#include "Node.h"
#include <iostream>
Node::Node()
{
cout << "1" << endl;
Node(Game(), 0.0);
}
Node::Node(double v)
{
cout << "2" << endl;
Node(Game(),v);
}
Node::Node(Game g, double v)
{
cout << "3" << endl;
numVisits = 0;
value = v;
game = g;
}
И вывод:
Node n(16);
cout << n.value << endl;
равно 0, когда оно должно быть 16.
Что я делаю неправильно?
Ответы
Ответ 1
Node(Game(),v);
в вашем конструкторе не делает то, что вы ожидали. Он просто создает временное без его использования и не действует. Затем он немедленно уничтожает это временное, когда управление течет через.
Правильный способ инициализации элементов в каждом конструкторе. Вы можете извлечь свой общий код в частной функции init() и вызвать его в каждом конструкторе, как показано ниже:
class Foo {
public:
Foo(char x);
Foo(char x, int y);
...
private:
void init(char x, int y);
};
Foo::Foo(char x)
{
init(x, int(x) + 3);
...
}
Foo::Foo(char x, int y)
{
init(x, y);
...
}
void Foo::init(char x, int y)
{
...
}
С++ 11 позволит конструкторам вызывать другие одноранговые конструкторы (известные как делегирование), однако большинство компиляторов еще не поддерживали это.
Ответ 2
Функция, которую вы пытаетесь использовать, называется делегирование конструкторов, которая является частью С++ 0x. Используя этот синтаксис, ваш второй конструктор станет
Node::Node(double v)
: Node(Game(),v)
{
cout << "2" << endl;
}
Ответ 3
Node::Node(double v)
{
cout << "2" << endl;
Node(Game(),v); // 1
}
- Создает безымянный объект, который не сохраняется за пределами этого выражения. Таким образом, это не влияет на исходный объект
value
, на котором создается экземпляр одиночного аргумента. Вам также необходимо понять, что этот временный объект полностью отличается от исходного объекта построения.
Однако вы можете продлить время жизни этого временного объекта с помощью ссылки const, т.е.
Node::Node(double v)
{
cout << "2" << endl;
const Node& extendTemporay = Node(Game(),v);
value = extendTemporary.value ; // Just trivial example;
// You can simply do it by value = v;
}
Ответ 4
Вы можете сделать это так, где init() - частный метод:
#include "Node.h"
#include <iostream>
Node::Node()
{
cout << "1" << endl;
init(Game(), 0.0);
}
Node::Node(double v)
{
cout << "2" << endl;
init(Game(),v);
}
Node::Node(Game g, double v)
{
cout << "3" << endl;
init(g,v)
}
void Node::init(Game g, double v)
{
numVisits = 0;
value = v;
game = g;
}
Ответ 5
В двух словах:
#include <iostream>
#include "Node.h"
Node::Node()
: game(Game()), value(0.), numVisits(0)
{
std::cout << "1" << std::endl;
}
Node::Node(double v)
: game(Game()), value(v), numVisits(0)
{
std::cout << "2" << std::endl;
}
Node::Node(Game g, double v)
: game(g), value(v), numVisits(0)
{
std::cout << "3" << std::endl;
}
Как сказали все, вы не можете вызвать перегрузку конструктора из конструктора. Делегация - это непревзойденная функция, с которой мы встретимся с С++ 11.
Это не так много текста для ввода, не ленитесь.