2013-12-25 3 views
2

У меня есть следующий код;Что делает оператор =, когда мы используем его на двух структурах?

#include <iostream> 

using namespace std; 

struct Slog1 
{ 
    char ime1; 
    int broj1; 
}; 

struct Slog2 
{ 
    char ime2; 
    int broj2; 
}; 
int main() 
{ 
    Slog1 aSlog, bSlog; 
    Slog2 cSlog; 

    aSlog = bSlog; // 1 
    bSlog.ime1 = cSlog.ime2; // 2 
    aSlog = cSlog; // 3 

} 

Теперь я объявил:

Slog1 aSlog, bSlog; 
Slog2 cSlog; 

Те Struct переменные, которые я очень хорошо понимаю. И теперь у меня есть это:

aSlog = bSlog; // 1 
bSlog.ime1 = cSlog.ime2; // 2 
aSlog = cSlog; // 3 
  1. Что это делает именно? Он компилируется отлично, но я не уверен, что это так.
  2. Этот я хорошо понимаю, он устанавливает член ime1 из bSlog значения элемента ime2 в структуре cSlog.
  3. не компилируется по какой-то причине, но это так же, как 1.
+2

http://stackoverflow.com/questions/2302351/assign-one-struct-to-another-in-c – akonsu

+0

@akonsu Что означает тот же «тип»? Можете ли вы уточнить? – user2943407

+0

«тот же тип» означает, что вы можете назначить одну переменную другой, если они являются одинаковыми структурами (типами), и вы не можете сделать это, если они различны, как в вашем третьем случае. – akonsu

ответ

8
aSlog = bSlog; // 1 

Каждый член aSlog будет установлен в соответствующее значение bSlog. Это неглубокая копия, поэтому любые указатели, которые могут быть в этой структуре, будут иметь одинаковое значение. Поскольку aSlog и bSlog - это тот же тип, это неявный оператор присваивания копий.

bSlog.ime1 = cSlog.ime2; // 2 

Это установит ime1 члена bSlog к значению ime2 из cSlog. Для этого используется оператор присваивания копий для char.

aSlog = cSlog; // 3 

Это не должно составить, поскольку нет ничего в этом коде, который говорит компилятору, как преобразовать тип Slog1 в тип Slog2. Вам понадобится конструктор преобразования (конструктор, объявленный в Slog1, который принимает параметр Slog2).

struct Slog2 
{ 
    char ime2; 
    int broj2; 
}; 

struct Slog1 
{ 
    char ime1; 
    int broj1; 
    // ... 
    // conversion-constructor 
    Slog1(const Slog2& s2) : ime1(s2.ime2), broj1(s2.broj2) 
    { } 
    // copy-assignment conversion 
    Slog1& operator=(const Slog2& s2) 
    { 
     ime1 = s2.ime2; 
     broj1 = s2.broj2; 
     return *this; 
    } 
}; 
+1

Я бы структурировал первый абзац по-разному: поскольку они одного типа, и нет назначенного пользователем оператора присваивания, будет использоваться неявно созданное стандартное присваивание по умолчанию op. Этот неявно сгенерированный оператор выполняет задание копии по члену. – dyp

+1

* Nit-pick * (еще один;) 'void operator = (const Slog2 & s2)' Я бы сказал, что это не преобразование (см. [Class.conv]/1), а тип возврата должен (в конвенция) - 'Slog1 &'. Это не неявное преобразование, потому что 'Slog2 x; Slog1 temp = x; 'не является корректным, и ни один из стандартных прикладов (' static_cast' и т. Д., C-style casts) не позволяет сделать что-то вроде '(Slog1) x' только при присвоении op. – dyp

+0

@DyP Я не уверен, что я последую за вами на хорошо сформированной части. Причина, по которой я не дал ему возвратной ценности, заключается в том, что она будет непоследовательна, но нет ничего, что помешало бы ему сделать это (я просто приводил пример). –

2
  1. Значения из bSlog копируются в aSlog
  2. aSlog имеет тип Slog1 и cSlog имеет тип Slog2 это означает, что разные типы то есть, как вы будете добавлять обугленного значение переменной Int
3

Slog1 и Slog2 совершенно несвязанные типы. Независимо от того, если вы дадите им один и тот же макет, компилятор откажется назначить один из другого, поскольку вы не предоставляете явных конструкторов преобразования /операторов-операторов/операторов-операторов.

3
aSlog = bSlog; // 1 

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

aSlog = cSlog; // 3 

Slog1 Классы и Slog2 не связаны между собой, так что это не будет компилироваться как есть, потому что вы не определили механизм для выполнения этого задания. Вы можете сделать это с помощью оператора присваивания в классе Slog1, который получает в качестве аргумента Slog2, конструктор преобразования в классе Slog1, который принимает в качестве аргумента Slog2 или operator Slog1 в классе , который в качестве вывода производит Slog1.

+0

Нет, неявно определенный оператор присваивания не выполняет «мелкую копию». Он вызывает оператор присваивания типа для каждого члена. –

2
  1. Это просто устанавливает aSlog (типа Slog1), равный bSlog (который также типа Slog1). Это прекрасно работает. Это так же просто, как установка одного int, равного другому int.

  2. Вы верны. Это работает, потому что Slog1.ime1 и Slog2.ime2 являются символами типа char.

  3. Это полностью отличается от (1). cSlog - это другой тип, чем aSlog (Slog2 для c, Slog1 для a), и вы не можете установить Slog1 равным Slog2. Это эквивалент установки char, равного int.

JUst a comment: выберите лучшие имена, чем slog, ime и broj. Просто используйте людей. Slog1 является мужчиной, char ime1 является его первым начальным, а int broj1 - его возрастом. Slog2 - женщина, а остальное - то же самое. Тогда вы поймете, что вы не можете установить aSlog (Мужской), равный cSlog (Female).

+0

'char' неявно конвертируется в' int' - это не очень хороший пример для использования. –

+0

Но не наоборот (по крайней мере, не теряя тонны точности). – CameronNemo

+0

Он все равно позволит вам это сделать (хотя и с предупреждением). Ваш Мужской = Женский пример более ясен и более подробно передает проблему. –

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