C++: Initialization of Inherited Field

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:

  1. Convert the Options class to string in the options get accessor.
  2. Eliminate the options property and, instead, implement a toString method that would call createOptions or just it's content


Related Topics



Leave a reply



Submit