C++: Initialization of inherited field
You need to make a constructor for A (it can be protected so only B can call it) which initializes m_int just as you have, then you invoke :A(0)
where you have :m_int(0)
You could also just set m_int = 0
in the body of B's constructor. It is accessible (as you describe) it's just not available in the special constructor syntax.
Why can't I access inherited protected fields in a derived constructor's member initialization list?
You can access them in Derived
, but they are members of Base
and cannot be initialized directly in the member initialization list of Derived
. This also wouldn't work if they were public
. Note that the Base
class is initialized before the members of Derived
are initialized.
To initialize the base, you can call its constructor in the Derived
's member initialization list:
class Derived : public Base
{
public:
Derived(int a, int b) : Base(a, b) { };
};
For more details, see here: https://en.cppreference.com/w/cpp/language/constructor
PS: Note that with respect to the member initialization list, there is also no difference to members that are private
in the base. All members of the base are inherited, and initialized before members of the derived are initialized.
You miss to initialize z
, and in your example there is no reason to use new
and delete
. If you fix the above, you get same output with this code:
int main()
{
Base b(10,20);
Derived d(10,20);
}
Last, but not least, if you plan to use Derived
polymorphically, you need to declare the destructor of Base
as virtual
.
Using initializer list for a struct with inheritance
With inheritance, each base class subobject of the aggregate is initialized like a member. So to aggregate initialization, Child
has two subobjects: Parent
, and i
. So you need two initializers in your braced-init-list:
Child c{ {}, 1 };
Also, in order for Child
to be an aggregate, all subobjects must be public. So you can't have private base classes.
Of course, this assumes that Visual Studio implements the feature correctly. VS2017 15.5 is not C++17 compliant, but 15.7 supports this.
Initialize parent's protected members with initialization list (C++)
It is not possible in the way you describe. You'll have to add a constructor (could be protected) to the base class to forward it along. Something like:
class Parent
{
protected:
Parent( const std::string& something ) : something( something )
{}
std::string something;
}
class Child : public Parent
{
private:
Child() : Parent("Hello, World!")
{
}
}
Initializing fields in inherited classes
If a base class requires a value to be provided by a derived class, the two most common ways are:
Require it in the constructor:
public readonly double Price;
protected BaseClass(double price)
{
this.Price = price;
}
Derived classes must pass the price into the constructor:
public Derived() : base(32)
{
}
Or, make it an abstract property:
public abstract double Price { get; }
Derived classes must provide some way to return the value (though where they get it is up to the derived class, which in many cases provides more flexibility):
public override double Price
{
get
{
return 32;
}
}
Initialization of members when inheriting from extern C struct
If you can use a c++11 compatible compiler then this would be a perfect use case for an initializer list using aggregate initialization.
mybuf() : buf{0, 0}
{}
brace initialization for inherited pod
base_pod_t
is an aggregate and the initialization you're performing is aggregate initialization.
From §8.5.1 [dcl.init.aggr]
1 An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).
2 When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order. Each member is copy-initialized from the corresponding initializer-clause. ...
However, der_pod_t
is not an aggregate because it has a base class. It's a POD, and the same rules for list initialization do not apply. Now, when the compiler sees a non-empty braced-init-list it'll first search for a constructor that takes an initializer_list
. If none are found it then attempts to match other constructors of the class. Since der_pod_t
has no constructors that take a single int
as argument, the error occurs.
c# inherited class initialization
I suppose you forgot to show us the Options
class constructor, but I guess it calls the createOptions()
method.
In C# you just can't call a base constructor wherever you want. The base constructor is always called before the given constructor starts. You may refer to this url to know more about constructor chaining:
http://www.yoda.arachsys.com/csharp/constructors.html
But you can get what you want by changing your architecture a little. As I see this, your options
property is a ToString()
of the Options class. You do not need this property to be ready at constructor time.
Some options:
- Convert the Options class to string in the options get accessor.
- Eliminate the options property and, instead, implement a toString method that would call createOptions or just it's content
Related Topics
Output Redirection Using Fork() and Execl()
What Does the Gcc Warning "Project Parameter Passing for X Changed in Gcc 7.1" Mean
Why Is the Copy Constructor Called When We Pass an Object as an Argument by Value to a Method
Std::Remove_If - Lambda, Not Removing Anything from the Collection
What Is the Purpose of a Declaration Like Int (X); or Int (X) = 10;
Speed Difference Between If-Else and Ternary Operator in C...
Is There a Standard Date/Time Class in C++
Best Practices for Recovering from a Segmentation Fault
How to Run the Preprocessor on Local Headers Only
Oracle Oci, Bind Variables, and Queries Like Id in (1, 2, 3)
Algorithm to Add or Subtract Days from a Date
C++ Function for Picking from a List Where Each Element Has a Distinct Probability
How to Compare Two Character Strings Statically at Compile Time
Ways to Detect Whether a C++ Virtual Function Has Been Redefined in a Derived Class