Assignment to an inherited structure - page 2

 
Vladislav Boyko #:

I didn't know I was assigning anything to "this". I thought I was calling a method.

You changed your code of this post #7 ? I think I answered while you was changing it, unless I misread (?). Sure you don't assign to this in your #7 code.

Oh, by the way, the presence of "this" was my mistake. "this" is not needed there:

But I still haven't tested it and don't know if it works (I assume it should)

Got it. Yes this version works though it's not better in terms of best practice and good design.
 
Alain Verleyen #:
You changed your code of this post #7 ? I think I answered while you was changing it, unless I misread (?). Sure you don't assign to this in your #7 code.

I have not edited any posts in this topic.

There are a lot of posts here with similar code, so it's not surprising if someone anyone misreads something.

[edit]

I’ve just edited this post to fix a potentially incorrect English translation (now crossed out)😁

 
Vladislav Boyko #:

I have not edited any posts in this topic.

There are a lot of posts here with similar code, so it's not surprising if someone anyone misreads something.

[edit]

I’ve just edited this post to fix a potentially incorrect English translation (now crossed out)😁

😶 
 
Vladislav Boyko #:

I wouldn't call this code either simple or transparent. A quick read might not reveal that there are different types in that expression. Or not different, I don’t know, 3 lines of code and you can already get confused.


Let's imagine that I want to extend the structure by adding another operator=

The code compiles, but I no longer understand anything. It would take me 1-2 hours of testing to figure out how it works. And then MQ will change something in the compiler again, and you'll get a hard-to-find bug.

I don't know what does confuse you in assignment (MQL checks if the types are applicable and shows errors or warnings if necessary), but in the second part of your message you added some other stuff and wrote that you don't like it - this is a bit strange, because it looks like you're opposed to yourself and just pretend that I argued. Nevertheless, I completely agree that having a Set method is ridiculous provided that there is operator= already. I used the Set method in my answer just because the OP used it, and I left assignment to this for the same reason - just to keep the original source code intact as much as possible. Also I support the idea for not using "using" in exchange to explicit call of inherited method MqlDateTime::operator=.
 
Vladislav Boyko #:

That code is as simple as a door, everything is transparent and obvious. I would just change the method name to make it clear that it accepts a different type of object:

It's simple as far as you're using just an assignment. If you embed an object with some interface methods (which is usually a case), then you'll need to dispatch every useful call via corresponding facade method to the internal object. This looks strange and requires routine copy&paste coding, and thus is not simple at all.

If you're extending existing struct/class with some specific stuff using inheritance is a natural way.

If you need to combine multiple features from different structs/classes using composition is (probably!) a way to try.

In the presented task, I suppose, the 1-st scenario is more applicable.

And yes, I agree, that assignment to this looks strange from C++ point of view.

 
Stanislav Korotky #:
but in the second part of your message you added some other stuff and wrote that you don't like it - this is a bit strange, because it looks like you're opposed to yourself and just pretend that I argued.

Yes, the second part of that post looks questionable. I guess I didn’t express what I meant very clearly. Anyway, never mind.

Stanislav Korotky #:

It's simple as far as you're using just an assignment. If you embed an object with some interface methods (which is usually a case), then you'll need to dispatch every useful call via corresponding facade method to the internal object. This looks strange and requires routine copy&paste coding, and thus is not simple at all.

If you're extending existing struct/class with some specific stuff using inheritance is a natural way.

If you need to combine multiple features from different structs/classes using composition is (probably!) a way to try.

In the absence of multiple inheritance (at least interfaces), I personally would not abuse inheritance for relatively complex things.
 
I apologize for responding so late, as I have only just now gotten around to reading your answers.

I think I made the biggest mistake when I gave the simplest example possible and chose an inappropriate method name (Set). The truth is that in my code, I sometimes use inheritance for structures (classes) in which I want to inherit all data members and not add any new ones, just add some new methods. In some cases, it is necessary to ensure that data of the original type can be assigned to data of the inherited type. My original solution may not be entirely correct programming practice, but it worked quite simply and intuitively for me. Now I am faced with the task of replacing this no longer working practice in my code. I am glad that you have suggested several possible ways to do this, and I thank you all very much for that. To summarize, there are at least three possible ways. The following examples are only to illustrate the problem discussed and would have no practical significance.

The first one:

struct ExtDateTime1 : public MqlDateTime
  {
   using MqlDateTime:: operator =;
  };

void Assignment1(void)
  {
   MqlDateTime
      dt;
   ExtDateTime1
      edt1, edt2;
   ::TimeCurrent(dt);
   // MqlDateTime type assignment
   edt1 = dt;
   // ExtDateTime type assignment
   edt2 = edt1;
  }

The second one:

struct ExtDateTime2 : public MqlDateTime
  {
private:
   MqlDateTime dt;
public:
   void SetMqlDateTime(const MqlDateTime& value)
     {
      dt = value;
     }
  };

void Assignment2(void)
  {
   MqlDateTime
      dt;
   ExtDateTime2
      edt1, edt2;
   ::TimeCurrent(dt);
   // MqlDateTime type assignment
   edt1.SetMqlDateTime(dt);
   // ExtDateTime type assignment
   edt2 = edt1;
  }

The third one:

struct ExtDateTime3 : public MqlDateTime
  {
   void SetMqlDateTime(const MqlDateTime& value)
     {
      MqlDateTime::operator=(value);
     }
  };

void Assignment3(void)
  {
   MqlDateTime
      dt;
   ExtDateTime3
      edt1, edt2;
   ::TimeCurrent(dt);
   // MqlDateTime type assignment
   edt1.SetMqlDateTime(dt);
   // ExtDateTime type assignment
   edt2 = edt1;
  }

For my problem, the first method will probably be the most suitable, even though it may not be the best programming practice.

Once again, thank you all for your participation.

 
Petr Nosek #:
I apologize for responding so late, as I have only just now gotten around to reading your answers.

I think I made the biggest mistake when I gave the simplest example possible and chose an inappropriate method name (Set). The truth is that in my code, I sometimes use inheritance for structures (classes) in which I want to inherit all data members and not add any new ones, just add some new methods. In some cases, it is necessary to ensure that data of the original type can be assigned to data of the inherited type. My original solution may not be entirely correct programming practice, but it worked quite simply and intuitively for me. Now I am faced with the task of replacing this no longer working practice in my code. I am glad that you have suggested several possible ways to do this, and I thank you all very much for that. To summarize, there are at least three possible ways. The following examples are only to illustrate the problem discussed and would have no practical significance.

The first one:

The second one:

The third one:

For my problem, the first method will probably be the most suitable, even though it may not be the best programming practice.

Once again, thank you all for your participation.

You can do :

void OnStart(void)
 {
  ExtDateTime5 edt;
  TimeCurrent(edt);
 }

Could you explain why you want to inherit while your (example) code doesn't seem to use inheritance ? It's not to insist about bad or best practice, I am just curious and maybe I could learn something new.

 
Petr Nosek #:

Not sure if this will help, but I'll leave it here just in case.

Using the implicit copy constructor of the base class:

class A
  {
protected:
   int a;
   int b;
public:
   A(int _a, int _b) : a(_a), b(_b) {}
  };

class B : public A
  {
public:
   int sum() const { return a + b; }
   
public:
   B(const A& obj) : A(obj) {}
  };

void OnStart()
  {
   A a1(11, 22);
   B b(a1);
   Print(b.sum());
  }
 
Vladislav Boyko #:
Using the implicit copy constructor of the base class:

I added to that code the use of the base class's implicit operator=:

class A
  {
protected:
   int a;
   int b;
public:
   A(int _a, int _b) : a(_a), b(_b) {}
  };

class B : public A
  {
public: using A::operator=;

public:
   int sum() const { return a + b; }
   
public:
   B(const A& obj) : A(obj) {}
  };

void OnStart()
  {
   A a1(11, 22);
   A a2(33, 44);
   B b(a1);
   Print("#1: ", b.sum());
   b = a2;
   Print("#2: ", b.sum());
  }