I don't know which version introduced the change, but until relatively recently it was possible to create a descendant of a structure and assign the "value" of its ancestor to this descendant:
From build 5260.
If I add an operator definition (see below) to the struct, there will be no error during compilation, but if I use this assignment somewhere in the program, a stack overflow will occur:
Yes because the possibility to assign to "this" is an "MQL4 feature" which is no more accepted recommended.
Of course, I can use the operator definition to assign each individual field (see below), but it seems a little impractical to me. This code works without any problems:
My question is whether it is possible to avoid assigning individual fields in some way?
Yes by not inheriting from MqlDateTime, but rather composing from it.
Your example is a typical overuse of inheritance, ExtDateTime is NOT a MqlDateTime, ExtDateTime HAS a MqlDatetime.
struct MyDateTime { MqlDateTime dt; void Set(const MqlDateTime& value) { dt = value; } };
I don't know what version this change was introduced in, but until recently it was possible to create a child of a structure and assign the "value" of its parent to that child:
This is no longer possible and the compiler returns an error.
If I add the operator definition (see below) to the structure, no error occurs at compile time, but if I use this assignment somewhere in the program, a stack overflow occurs:
Of course, I could use an operator definition to assign each individual field (see below), but I find that a bit impractical. This code works without a problem:
My question is: is there any way to avoid assigning individual fields?
You can use the previous syntax perfectly well. The only thing you should add is the using declaration:
struct ExtDateTime : public MqlDateTime { using MqlDateTime:: operator =; void Set( const MqlDateTime& value ) { this = value ; } };
It's very common to use inheritance over composition when it makes sense. It's technically simpler and more intuitive to process structures with a common core in the same way, without bells and whistles.
You can use the previous syntax perfectly well. The only thing you should add is the using declaration:
It's very common to use inheritance over composition when it makes sense. It's technically simpler and more intuitive to process structures with a common core in the same way, without bells and whistles.
I don't recommend it. Though if you insist, better to do it this way :
struct ExtDateTime : public MqlDateTime { using MqlDateTime::operator =; void Set(const MqlDateTime& value) { *this = value; } };
I think a lot of people asking for the "using" feature in MQL5 for years will not agree with you.
I prefer to write code simple and readable (specifically, without unneeded facades, as you suggested in the post #1 for this case).
I prefer to write code simple and readable (specifically, without unneeded facades, as you suggested in the post #1 for this case).
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:
struct MyDateTime { private: MqlDateTime dt; public: void SetMqlDateTime(const MqlDateTime& value) { dt = value; } };
You can use the previous syntax perfectly well. The only thing you should add is the using declaration:
struct ExtDateTime : public MqlDateTime { using MqlDateTime:: operator =; void Set( const MqlDateTime& value ) { this = value ; } };
It's very common to use inheritance over composition when it makes sense. It's technically simpler and more intuitive to process structures with a common core in the same way, without bells and whistles.
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=
struct ExtDateTime : public MqlDateTime { using MqlDateTime:: operator =; void Set( const MqlDateTime& value ) { this = value; } void operator=(const ExtDateTime& other) { Print(__FUNCTION__); } };
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 recommend it. Though if you insist, better to do it this way :
struct ExtDateTime : public MqlDateTime { using MqlDateTime::operator =; void Set(const MqlDateTime& value) { *this = value; } };
I would get rid of the 'using' operator:
struct ExtDateTime : public MqlDateTime { void setMqlDateTime(const MqlDateTime& value) { this.MqlDateTime::operator=(value); } };
Although I haven't tested whether it works.
I would get rid of the 'using' operator:
Although I haven't tested whether it works.
You can't get rid of the 'using' if you want to assign to this.
This topic exists because MQL allow the bad practice to assign to 'this'. You can't do that in C++.
So for people insisting to use such design, they should, at least, use the somewhat clearer syntax '*this = ...'
I think a lot of people asking for the "using" feature in MQL5 for years will not agree with you.
I prefer to write code simple and readable (specifically, without unneeded facades, as you suggested in the post #1 for this case).
How much people agree or not is irrelevant.
I didn't say anything against 'using' in general (could be interesting though), I said it's a poor solution to the bad practice to assign 'this' as in the original post.
I am talking about good practices and known OOP design patterns. Not about what some coders subjectively find "simple and readable". You prefer your solution, it's fine.
This topic exists because MQL allow the bad practice to assign to 'this'.
I didn't know I was assigning anything to "this". I thought I was calling a method.
Oh, by the way, the presence of "this" was my mistake. "this" is not needed there:
struct ExtDateTime : public MqlDateTime { void setMqlDateTime(const MqlDateTime& value) { MqlDateTime::operator=(value); } };
But I still haven't tested it and don't know if it works (I assume it should)
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
I don't know which version introduced the change, but until relatively recently it was possible to create a descendant of a structure and assign the "value" of its ancestor to this descendant:
Now this is no longer possible and the compiler returns an error.
If I add an operator definition (see below) to the struct, there will be no error during compilation, but if I use this assignment somewhere in the program, a stack overflow will occur:
Of course, I can use the operator definition to assign each individual field (see below), but it seems a little impractical to me. This code works without any problems:
My question is whether it is possible to avoid assigning individual fields in some way?