With what access specifier should constructors of an abstract class be declared?
In the documentation, the constructor of an abstract class is declared with the access specifier public:
https://www.mql5.com/en/docs/basis/oop/abstract_type
class CAnimal { public: CAnimal(); // Constructor virtual void Sound() = 0; // A pure virtual function private: double m_legs_count; // The number of the animal's legs };
But what's the point if the abstract class cannot be instantiated?
Wouldn't it be more logical to declare an abstract class constructor with a protected access specifier?
class A { protected: A(int value) : m_value(value) {} int m_value; public: virtual int method() = 0; }; class B : public A { public: B() : A(0) {} int method() override { return(++m_value); } }; void OnStart() { B b; Print(b.method()); }
Is it possible to define the constructor body after the class description if an initialization list is used?
Here is an example without an initialization list:
class Foo { private: int m_a; int m_b; int m_c; public: Foo(int a, int b); }; Foo::Foo(int a,int b) // Defining the constructor body after the class description { m_a = a; m_b = b; m_c = a + b; }
Now let's add the initialization list:
class Foo { private: const int m_a; const int m_b; int m_c; public: Foo(int a, int b) : m_a(a), m_b(b) { // Can this constructor body be defined after the class description? m_c = a + b; } };
With what access specifier should constructors of an abstract class be declared?
In the documentation, the constructor of an abstract class is declared with the access specifier public:
But what's the point if the abstract class cannot be instantiated?
Wouldn't it be more logical to declare an abstract class constructor with a protected access specifier?
Is it possible to define the constructor body after the class description if an initialization list is used?
Here is an example without an initialization list:
Now let's add the initialization list:
Thanks a lot!
Yes, that is possible. You specify it just like you do inside the class declaration. There is no difference.
Do I understand correctly?
class Foo { private: const int m_a; const int m_b; int m_c; public: Foo(int a, int b); void print() { PrintFormat("a %i, b %i, c %i", m_a, m_b, m_c); } }; Foo::Foo(int a, int b) : m_a(a), m_b(b) { m_c = a + b; print(); } void OnStart() { Foo a(1, 2); }
So the answer is yes it's more logical to use a protected constructor for abstract classes. We could even have argue it should not be allowed by the compiler to use a public constructor for an abstract class, isn't ?
I don't get your point. Any programming language, as MQL in our case, is "compiler level concepts, helping the coder to use as intended". What do you mean by the second part about binary representation ?
So the answer is yes it's more logical to use a protected constructor for abstract classes. We could even have argue it should not be allowed by the compiler to use a public constructor for an abstract class, isn't ?
I don't get your point. Any programming language, as MQL in our case, is "compiler level concepts, helping the coder to use as intended". What do you mean by the second part about binary representation ?
I noticed one interesting feature.
A parametric constructor allows the use of a private destructor:
class Foo { public: Foo(int) { Print(__FUNCSIG__); } Foo() { Print(__FUNCSIG__); } private: ~Foo() { Print(__FUNCSIG__); } }; void OnStart() { Foo obj1(1); // OK Foo obj2; // 'Foo::~Foo' - cannot access private member function }
That is, the following program will compile and work:
void OnStart() { Foo obj1(1); }
We can even use the operator new:
void OnStart() { Foo* obj1 = new Foo(1); // OK }
But this object cannot be deleted:
void OnStart() { Foo* obj1 = new Foo(1); // OK delete obj1; // 'obj1' - cannot access private member function }
This feature is interesting because the ability to create an instance depends on which constructor is used (parametric or default)
Yes, if I am not mistaking...
I checked and it works, thanks!
I would certainly like this syntax to be documented. Because I can't be sure it will always work unless it's documented. But I'm saying this in general. I think this constructor body definition will always work
I noticed one interesting feature.
A parametric constructor allows the use of a private destructor:
That is, the following program will compile and work:
We can even use the operator new:
But this object cannot be deleted:
This feature is interesting because the ability to create an instance depends on which constructor is used (parametric or default)
I checked and it works, thanks!
I would certainly like this syntax to be documented. Because I can't be sure it will always work unless it's documented. But I'm saying this in general. I think this constructor body definition will always work
- 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 created this topic in order to avoid creating a separate topic for each OOP question (I have already created several of these).