3

I have the following code;

#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

}

Now, I have declared:

Slog1 aSlog, bSlog;
Slog2 cSlog;

Those are struct variables which I understand very well. And now I have these:

aSlog = bSlog; // 1
bSlog.ime1 = cSlog.ime2; // 2
aSlog = cSlog; // 3
  1. What does it do exactly? It compiles fine but I'm not sure it does.
  2. This one I understand well, it sets the member ime1 of bSlog the value of the member ime2 in the cSlog struct.
  3. Doesn't compile for some reason, but it's the same as 1.
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
user2943407
  • 409
  • 3
  • 5
  • 13
  • 2
    http://stackoverflow.com/questions/2302351/assign-one-struct-to-another-in-c – akonsu Dec 25 '13 at 01:18
  • @akonsu What does the same 'type' mean? Can you elaborate? – user2943407 Dec 25 '13 at 01:18
  • "the same type" means that you can assign one variable to another if they are the same structures (types), and you cannot do it if they are different as in your third case. – akonsu Dec 25 '13 at 01:20
  • Well, they are the same type, aren't they? Both have an int and char defined inside. – user2943407 Dec 25 '13 at 01:21
  • 1 and 3 are not the same because the structure is different (the property names). When you say, "this object" = "that object" you're changing the memory pointed to point to the other. – SQLMason Dec 25 '13 at 01:21
  • they are not the same type, they are different types although these two types have similar members. – akonsu Dec 25 '13 at 01:23
  • Oh, you mean the name "Slog1" and "Slog2" right? – user2943407 Dec 25 '13 at 01:24
  • yes, `Slog1` and `Slog2` are different types. – akonsu Dec 25 '13 at 01:25
  • Do **NOT** close this as a duplicate of a `c`-tagged question! There may well be an existing good Q&A for C++, but C++ and C differ greatly in this regard. – Ben Voigt Dec 25 '13 at 02:57

5 Answers5

8
aSlog = bSlog; // 1

Each member of aSlog will be set to the corresponding value of bSlog. This is a shallow copy, so any pointers that may be in this structure will be set to the same value. Since aSlog and bSlog are the same type, this is an implicit copy-assignment operator.

bSlog.ime1 = cSlog.ime2; // 2

This will set the ime1 member of bSlog to the value of ime2 of the cSlog. This uses the copy-assignment operator for char.

aSlog = cSlog; // 3

This should not compile as there is nothing in this code that tells the compiler how to convert a type of Slog1 into a type of Slog2. You would need a conversion constructor (a constructor declared in Slog1 that takes a Slog2 parameter).

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;
    }
};
Zac Howland
  • 15,777
  • 1
  • 26
  • 42
  • 1
    I'd structure the first paragraph differently: Since they're of the same type, and there's no user-provided assignment operator, the implicitly generated default copy-assignment op will be used. This implicitly generated operator does a member-wise copy assignment. – dyp Dec 25 '13 at 01:28
  • 1
    *Nit-pick* (another one ;) `void operator=(const Slog2& s2)` I'd argue that this isn't a conversion (see [class.conv]/1), and the return type should (per convention) be `Slog1&`. It's not an implicit conversion because `Slog2 x; Slog1 temp = x;` is not well-formed, and none of the standard casts (`static_cast` etc., C-style casts) allow something like `(Slog1)x` via only the assignment op. – dyp Dec 25 '13 at 01:36
  • @DyP I'm not sure I follow you on the well-formed part. The reason I didn't give it a return value is that it would be inconsistent, but there is nothing stopping him from doing it (I was just providing an example). – Zac Howland Dec 25 '13 at 01:38
  • If you only had the copy assignment op, then `Slog2 x; Slog1 y = x;` would be ill-formed. OTOH, if you only have the converting ctor, then `Slog2 x; Slog1 y; y = x;` *is* well-formed (by constructing a temporary of type `Slog` from `x` and assigning this temporary). -- What should the return type of the assignment op be inconsistent with? – dyp Dec 25 '13 at 01:41
  • I show both being implemented, so it should be well-formed all the way around. But what should an `operator=` return if its parameters are `type1` and `type2`? That is, should it return a `type1`, or a `type2`? – Zac Howland Dec 25 '13 at 02:34
  • @Zac: It should `return *this;` – Ben Voigt Dec 25 '13 at 02:59
  • @BenVoigt In general, I get that ... my point is when you have `type1 = type2` chaining it to `type1 = type2 = type3` makes little sense. – Zac Howland Dec 25 '13 at 03:16
3

Slog1 and Slog2 are completely unrelated types. No matter if you give them the same layout, the compiler will reject to assign one from the other, as long you're not providing explicit conversion constructors / assignment operators / cast operators.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
3
aSlog = bSlog; // 1

You didn't overload the assignment operator for class Slog1, so this uses the implicitly-declared and implicitly-defined assignment operator member function. The implicitly-defined assignment operator does a shallow copy.

aSlog = cSlog; // 3

The classes Slog1 and Slog2 are unrelated, so this won't compile as-is because you didn't define a mechanism to perform this assignment. You could do this with an assignment operator in class Slog1 that receives a Slog2 as an argument, a converting constructor in class Slog1 that takes a Slog2 as an argument, or an operator Slog1 in class Slog2 that produces a Slog1 as an output.

David Hammen
  • 32,454
  • 9
  • 60
  • 108
  • No the implicitly-defined assignment operator does not "do a shallow copy". It calls the type-appropriate assignment operator for each member. – Ben Voigt Dec 25 '13 at 02:58
2
  1. Values from bSlog are copied to aSlog
  2. aSlog is of type Slog1 and cSlog is of type Slog2 that means different types that is like you will add char value to int variable
Nick
  • 4,192
  • 1
  • 19
  • 30
2
  1. It simply sets the aSlog (of type Slog1) equal to bSlog (which is also of type Slog1). This works perfectly. It is just as simple as setting one int equal to another int.

  2. You are correct. This works because Slog1.ime1 and Slog2.ime2 are both of type char.

  3. This is completely different from (1). cSlog is a different type than aSlog (Slog2 for c, Slog1 for a), and you can not set a Slog1 equal to a Slog2. That is the equivalent of setting a char equal to an int.

JUst a comment: pick better names than slog, ime, and broj. Just use people. Slog1 is a male, char ime1 is his first initial, and int broj1 is his age. Slog2 is a female, and the rest is the same. Then you will understand that you can not set aSlog (a Male) equal to cSlog (a Female).

CameronNemo
  • 616
  • 3
  • 10