2017-01-17 2 views
0

Я новичок в C++ languge, и я знаком с языком java.C++ Поведение конструктора

в Java-мире, код выглядит нормально, но не в C++.

может кто-нибудь объяснить, почему оба конструктора называются?

class Position { 

    public: 

    Position(void) 
    { 
     std::cout<<"defualt constructor\n"; 
    } 

    Position(unsigned int row,unsigned int col) 
    { 
     std::cout<<"two Arguments constructor\n"; 
     row_index = row; 
     col_index = col; 
    } 

private: 
    unsigned int row_index; 
    unsigned int col_index; 
    }; 

class Tool 
{ 
public: 
    Tool(char Team,unsigned int row,unsigned int col) 
    { 
     pos = Position(row,col); 
     team = Team; 
    } 
    std::string To_string() 
    { 
     std::string str = "team: "; 
     str+= team; 
     str+= " pos: "; 
     str+= pos.To_string(); 
     return str; 
    } 
    char Get_team() 
    { 
     return team; 
    } 
private: 
    Position pos; 
    char team; // A or B 

}; 

int main(void) 
{ 
Tool t = Tool('A',1,3); 
return 0; 
} 

я намерен призвать к конструктору двумя аргументами

ВЫВОД:

Defualt конструктор

два Аргументы конструктора

+4

Код * is * ok на C++. Проблема в том, что вы используете Java в качестве модели для понимания и написания кода на C++. Не делай этого. – PaulMcKenzie

ответ

5

В Tool классе объект Position построен первый по умолчанию перед выполнением корпуса конструктора Tool является execu Тед. Затем вы создаете новый временный объект Position в корпусе конструктора Tool и используете его в присваиваете до pos.

Важной частью здесь является то, что строительство объекта является трехступенчатый процесс:

  1. Объект выделяется
  2. объект инициализируется и все его члены построены (здесь конструктор по Position умолчанию называется)
  3. конструктор объекта выполняется (здесь два аргумента Position конструктор вызывается)

Чтобы использовать конструктор с двумя аргументами Position, а не просто назначить объекту pos, вам нужно использовать список инициализаторов конструктора . Вы можете сделать это, изменив Tool конструктор, как это:

Tool(char Team,unsigned int row,unsigned int col) 
    : pos(row, col), // Initializes the `pos` object 
     team(Team)  // Initialize the `team` member 
{ 
    // No code needed, the members have already been initialized 
} 
+0

позвольте предположить, что массив инструментов «Свойство» вместо одного объекта, и каждая позиция больше на 1, как это можно сделать с помощью формата NAMEOFCLASS (аргументы ...): assign() {} – dids

+0

@ Если все элементы должны быть инициализированы одним и тем же «значением», то я предлагаю вам вместо этого использовать ['std :: vector'] (http://en.cppreference.com/w/cpp/container/vector), он имеет a [конструктор] (http://en.cppreference.com/w/cpp/container/vector/vector), который принимает количество элементов и значение по умолчанию для всех элементов. Если вам нужны разные значения, то вы просто не можете этого сделать, вам нужно перебрать массив в теле конструктора и назначить каждый элемент. –

+0

считают, что все элементы имеют разное значение, если я работаю с указанным вами методом, то для каждого элемента будет вызываться как конструктор (конструктор defualt, два конструктора Аргументов), так? это эффективность? это похоже на дублированный звонок. – dids

3

В C++ все переменные члены построены, прежде чем тело конструктора вводится. Ваш код по умолчанию автоматически создает позицию, а затем в теле конструктора создается другое Позиция и присваивает его ранее построенной.

Вам необходимо пройти параметры установки, используя список инициализации:

Tool(char Team,unsigned int row,unsigned int col) : pos(row, col), team(Team) { 
    // constructor now empty 
    } 

В общем, тело конструктора должен быть пустым.

0

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

При вводе тела конструктора Position(row,col) в pos = Position(row,col); создает временный объект Position, который присваивается pos.

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

Tool(char Team,unsigned int row,unsigned int col) 
: pos (row, col), team (Team) 
    { 
    } 

Почему код в Java, работает, как вы ожидаете , связано с тем, что вы всегда работаете с ссылками на объекты, а не на объекты, в качестве значений. И неинициализированный объект-член ссылается на в Java, будет инициализирован по умолчанию на null (если память обслуживается справа), пока вы не создадите объект, и присвойте ему ссылку на переменную-член.

Смежные вопросы