Pass Parameter to Base Class Constructor While Creating Derived Class Object

Pass Parameter to Base Class Constructor while creating Derived class Object

Use base member initialisation:

class B : public A
{
public:
B(int a) : A(a)
{
}
~B();
};

Pass inherited arguments to base class constructor, then do something in derived class constructor

One way you could do this is to make a variadic template constructor in the derived class that passes all of its arguments to the base class. Then you can do whatever additional stuff you want in the body of that constructor. That would look like

struct Base
{
Base (int) {}
Base(int, int) {}
//...
};

struct Derived : Base
{
template<typename... Args>
Derived(Args&&... args) : Base(std::forward<Args>(args)...) // <- forward all arguments to the base class
{
// additional stuff here
}
};

Passing parameters to the base class constructor

Like this:

public class DerivedClass : BaseClass
{
public DerivedClass(int derivedParam, String baseParam):base(baseParam)
{
}
}

The base keyword here calls the base class constructor that matches the provided parameter overload.

How to get around calling base class constructor from derived class with the same arguments?

You may use a using-declaration to

Using-declaration

[...] introduce base class members into derived class definitions.

[...]

Inheriting constructors

If the using-declaration refers to a constructor of a direct base of the class being defined (e.g. using Base::Base;), all constructors of that base (ignoring member access) are made visible to overload resolution when initializing the derived class.

If overload resolution selects an inherited constructor, it is accessible if it would be accessible when used to construct an object of the corresponding base class: the accessibility of the using-declaration that introduced it is ignored.

as such:

class B : public A {
using A::A;
};

Note the highlight that the accessibility of the using-declaration itself is ignored, meaning using A::A in the example needn't the be placed under public accessibility - what matters is the accessibility of the inherited constructors in B.

When creating a constructor in a derived class

Parameter is not the field. When you write parameter names to your derived classes constructor like Derived(int m_Par=1,int m_Pro=2,int m_Pub=3) it doesn't match with the fields. You are matching fields with the parameters in the function body if you want so.

If you want to initialize a private field in base class you can use something like that.

class Base{
private: int m_Par;
protected: int m_Pro;
public:int m_Pub;

Base(int m_Par){
this->m_Par = m_Par;
}

int getM_Par(){
return this->m_Par;
}
};
class Derived :public Base{
public:Derived(int m_Par=1,int m_Pro=2,int m_Pub=3);
void Func();
};
Derived::Derived(int m_Par,int m_Pro,int m_Pub) : Base(m_Par)
{
this->m_Pro=m_Pro;
this->m_Pub=m_Pub;
}

int main(){
Derived d(10,5,3);
std::cout<<"M_Par value: "<<d.getM_Par();
return 0;
}

EDIT:
In the code below you wrote this->m_Pro = m_Pro; and this->m_Pub=m_Pub;. Those code blocks assigns the values taken from parameters to your base classes fields. When you write Derived :: Derived(int m_Par =1, int m_Pro=2, int m_Pub=3) what you are doing is that if user doesn't pass any parameters to the function your parameters will have default values that you have assigned. So parameters and the fields are not the same. The fields you wrote in the base class are belong to base class but parameters are local variables belong to the function you passed into.

Derived::Derived(int m_Par,int m_Pro,int m_Pub) : Base(m_Par)
{
this->m_Pro=m_Pro;
this->m_Pub=m_Pub;
}

Passing Parameters to Base Class Constructors C++

Yes there is, in the header file:

class Derived : public Base
{
int t;
public:
Derived(int y); // Declaration of constructor
};

while in the cpp file:

Derived::Derived(int y) : Base(t) { // Definition of constructor
t = y;
}

Member initializer lists are allowed in the definition of a class constructor as well as in inline in-class definitions. In case you're interested, I also recommend to take a look at cppreference for two small caveats regarding the order of initialization and the fact that members will be initialized before the compound constructor body is executed.

Can I pass arguments to a base constructor from a derived class's default constructor?

Yes, you can do this if you make the arrays static:

public class EuchreDeck : Deck
{
private static readonly string[] values = new string[] { "9", "10", "J", "Q", "K", "A" };
private static readonly string[] suits = new string[] { "clubs", "spades", "hearts", "diamonds" };

public EuchreDeck() : base(values, suits)
{

}
}

The reason why you can't use it as you had with instance-level members is because it's not legal to do so. This comes from the C# specification 10.10.1 Constructor Initializers where it states:

An instance constructor initializer cannot access the instance being
created. Therefore it is a compile-time error to reference this in an
argument expression of the constructor initializer, as is it a
compile-time error for an argument expression to reference any
instance member through a simple-name.

By switching the arrays to be static, they are no longer accessed via the instance but rather by the EuchreDeck type.


That said, I might suggest you take a slight tweak on the design. Maybe use a factory to create these specialized decks for you rather than their constructors.

As an example, maybe refactor something like this:

Change your base Deck to just take the set of cards:

public abstract class Deck
{
public List<Card> Cards;
protected Deck(IEnumerable<Card> cards)
{
this.Cards = new List<Card>(cards);
}
}

Then have the factory setup like this:

public class EuchreDeck : Deck
{
private EuchreDeck(IEnumerable<Card> cards) : base(cards)
{

}

public class Factory : DeckFactory
{
private static readonly string[] Values = new string[] { "9", "10", "J", "Q", "K", "A" };
private static readonly string[] Suits = new string[] { "clubs", "spades", "hearts", "diamonds" };

public static EuchreDeck Create()
{
var cards = CreateCards(Values, Suits);
return new EuchreDeck(cards);
}
}
}

Instantiation/usage as:

EuchreDeck.Factory.Create();

You could play around with the factory usage. I just nested it in the class so you couldn't create a EuchreDeck with an invalid set of cards. Your DeckFactory base would have your conversion method (which looks like you currently have in your Deck constructor)

Beyond that, I'm not sure if you have a specific need for a EuchreDeck; I'm assuming you have other methods associated with it? If not, you could probably ditch the class altogether and just let the factory create a Deck with the needed cards.

c++ constructor pass a reference to a base class object

Technically, you are able to define a copy constructor of DataModel taking a ComputationalModel reference as a function parameter.

DataModel d1(/* Parameter... */);
ComputationModel c1(/* Parameter... */);

DataModel d2(d1); // copy-construct instance, d1 passed as refence to the base class
DataModel d3(c1); // same behavior

This will, however, almost never be a good idea, because copy-construction of an object typically requires the state of the object to copy from. When you pass a base class reference, you drop all data members of the derived class instance, which leaves the newly created object in a state that is hard to guess from client code.

The default copy constructor has a const-qualified reference argument to the exact same type, in your case:

DataModel(const DataModel& other) = default;

which brings me to your last question

Why would the default copy constructor not be sufficent here?

This is hard to tell without seeing the rest of your inheritance hierarchy. A guideline would be: if the copy constructor of all data members in the hierarchy do the right thing, then a defaulted copy constructor does the right thing as well.



Related Topics



Leave a reply



Submit