Подтвердить что ты не робот

Перегрузка конструктора в С++

Перегрузка 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.

Что я делаю неправильно?

4b9b3361

Ответ 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. Это не так много текста для ввода, не ленитесь.