answersLogoWhite

0


Best Answer

Yes, D requires constructors, because all classes require constructors. However, whether you need to actually define them or not depends on whether B has any constructors other than a default constructor and a copy constructor. To understand why all classes must have constructors you need to understand how the compiler-generated constructors work.

All classes must have at least two constructors, one of which must be a copy constructor. If you do not define any constructors at all, the compiler automatically generates a default constructor (with no parameters) and a copy constructor. If you define any constructor, the compiler only generates the copy constructor unless you define your own. The compiler also generates an assignment operator and a destructor unless you provide your own.

In many cases the compiler-generated constructors will be sufficient for your needs thus there is no need to define your own in these cases. However, if your class contains one or more pointers to memory that is exclusive to each instance of a class (not shared amongst them), then you must provide your own constructors, as well as an assignment operator and a destructor, in order to manage that memory correctly. This is because the compiler-generated versions will treat all pointers as being pointers to shared memory and will simply copy their addresses, not what they contain. You must override this behaviour and ensure that those pointers are deep-copied; copying the memory itself, not just the address.

Constructors exist in order to initialise member variables. Even if your class has no member variables and therefore no real need for constructors, the compiler-generated constructors will still exist, as will the assignment operator and destructor, and it is important that you fully understand how these constructors work so that you will know exactly when you need to define your own and when you do not.

Consider the following example:

#include <iostream>

class B {

public:

B():m_data(0){ std::cout << "B::B()" << std::endl; }

B(const B& b):m_data(b.m_data){ std::cout << "B::B(const B&)" << std::endl; }

B& operator= (const B& b){ m_data = b.m_data; std::cout << "B::operator= (const B&)" << std::endl; return( *this ); }

virtual ~B(){ std::cout << "B::~B()" << std::endl; }

void SetData(const int i){m_data=i; std::cout << "B::m_data=" << m_data << std::endl; }

int GetData(){return m_data;}

private:

int m_data;

};

class D: public B {}; // no members or constructors defined.

int main()

{

D d1; // default constructor

std::cout << "d1.GetData()==" << d1.GetData() << std::endl;

d1.SetData( 100 );

std::cout << "d1.GetData()==" << d1.GetData() << std::endl;

D d2(d1); // copy constructor -- same as: D d2 = *d;

std::cout << "d2.GetData()==" << d2.GetData() << std::endl;

d1.SetData( 200 );

std::cout << "d1.GetData()==" << d1.GetData() << std::endl;

std::cout << "d2.GetData()==" << d2.GetData() << std::endl;

d2 = d1; // assignment operator

std::cout << "d2.GetData()==" << d2.GetData() << std::endl;

std::cout << std::endl;

return(0);

} // All objects fall from scope here.

Output:

B::B()

d1.GetData()==0

B::m_data=100

d1.GetData()==100

B::B(const B&)

d2.GetData()==100

B::m_data=200

d1.GetData()==200

d2.GetData()==100

B::operator= (const B&)

d2.GetData()==200

B::~B()

B::~B()

Since we provided no constructors in D it is difficult to see exactly what is going on here. In the main function we initially declare d1 to be of type D, but the first line of output is B::B(). Clearly the base class constructor is being invoked but it is not clear exactly how it was invoked. You'd be forgiven for thinking that since D inherits from B then it must inherit B's default constructor, but you cannot inherit constructors any more than you can inherit friends, operators or destructors from a base class. They are part of the interface but they are not part of the inheritable interface.

The answer, of course, lies in the fact the compiler has generated constructors for us Behind the Scenes. But since we don't have access to them we cannot trace them. So let's just clarify exactly what's going on by explicitly declaring constructors exactly as the compiler would have generated them for us. Let's also include some trace code so that we can see how they relate to the existing traces:

class D: public B {

public:

D():B(){ std::cout << "D::D()" << std::endl; }

D(const D& d):B(d){ std::cout << "D::D(const D&)" << std::endl; }

D& operator= (const D& d){ B::operator=( d ); std::cout << "D::operator= (const D&)" << std::endl; return( *this ); }

~D(){ std::cout << "D::~D()" << std::endl; }

};

Output:

B::B()

D::D()

d1.GetData()==0

B::m_data=100

d1.GetData()==100

B::B(const B&)

D::D(const D&)

d2.GetData()==100

B::m_data=200

d1.GetData()==200

d2.GetData()==100

B::operator= (const B&)

D::operator= (const D&)

d2.GetData()==200

D::~D()

B::~B()

D::~D()

B::~B()

Now things are somewhat clearer. Although B::B() looks like it was invoked before D::D(), they were actually invoked the other way around. Here's the default constructor for D:

D():B(){ std::cout << "D::D()" << std::endl; }

Note that before we enter the construction body (which contains the trace) we explicitly call the default constructor of B, hence it appears to be invoked first. However, this is, in fact, the correct order of events since we cannot construct an instance of D unless we first construct an instance of B. Only when B has been fully constructed can we then construct D.

Note also that even if we'd omitted the call to B() in the initialisation list, it would have been invoked automatically for us. That is, if we do not specify a base class constructor, the default constructor is invoked automatically. This fact is vital when it comes to declaring copy constructors:

D(const D& d):B(d){ std::cout << "D::D(const D&)" << std::endl; }

Here, we've called the base class copy constructor from the initialisation list: B(d). We have to do this because if we omit it, we'll end up calling the default constructor instead, which is not what we expect of a copy constructor. Here's the output trace snippet we'd have encountered had we omitted it:

d1.GetData()==100

B::B()

D::D(const D&)

d2.GetData()==0

Clearly, d2 cannot be a copy of d1 if their base class members differ, hence we must explicitly call the base class copy constructor (just as the compiler-generated copy constructor did).

Note that the assignment operator is not a constructor (it applies to existing objects only) and therefore does not have an initialisation list. However, the function body invokes the base class method, just as the compiler-generated version did.

The remainder of the output is fairly self-explanatory but note that destruction occurs in the reverse order of construction, thus D must be destroyed before B can be destroyed. Note also that since D is derived from B, B's constructor must be declared virtual. This is required because if we held a pointer to a derived class' base class and subsequently destroyed it, we would rightly expect the derived class' constructor to be invoked first. But if B's constructor were not virtual, we would end up destroying B alone, leaving an invalid instance of D in memory with no way to destroy it (a memory leak).

User Avatar

Wiki User

10y ago
This answer is:
User Avatar
More answers
User Avatar

Wiki User

10y ago

All classes require constructors. Even if you declare none, the compiler will automatically generate a default constructor (which invokes the base class default constructor) and a copy constructor (which invokes the base class copy constructor). But if you define any constructor, you lose the default constructor (the copy constructor is always generated).

In this particular case the compiler-generated constructors may suffice, in which case you need not define your own. However, if the base class has other constructors besides a default and copy constructor, you may wish to add similar constructors to your derived class in order to make use of them.

Another cavaet is that if either or both the default and copy constructors of the base class have been defined but are not implemented (disabled), you must also disable them in the derived class, as well as provide user-defined constructors that match the base class constructors.

Remember that you invoke specific base class constructors via the derived class constructor initialisation list, as follows:

class base

{

public:

base(): m_data(0) {}

base( const base& rhs ) : m_data(0) {}

virtual ~base() {}

base& operator= ( const base& rhs ) { m_data=rhs.m_data; return( *this ); }

private:

int m_data;

};

class derived : public base

{

public:

derived(): base() {}

derived( const derived& rhs ) : base( rhs ) {}

};

Note also that unless you define your own, a destructor and a default assignement operator are also generated by the compiler. However, the base class destructor must be declared virtual to ensure correct tear-down. The compiler-generated destructor of a base class is always declared non-virtual. In the above example, there is no need to declare either a destructor nor an assignement operator in the derived class, since the compiler-generated versions will behave accordingly.

This answer is:
User Avatar

User Avatar

Wiki User

11y ago

Am not sure what it is you are actually asking. Class D inherits all the protected and public members of class B. It doesn't need any data members of its own, but in order to be of any use it must override one or more of the virtual methods declared in class B, otherwise there's not much point in deriving from class B.

This answer is:
User Avatar

Add your answer:

Earn +20 pts
Q: Class D is derived from class B The class D does not contain any data members of its own Does the class D require constructors?
Write your answer...
Submit
Still have questions?
magnify glass
imp
Continue Learning about Engineering

How many constructors may be defined for a class?

As many as are required for the class to function. All classes other than static classes require at least one constructor. Most classes will also provide copy and move constructors (with corresponding copy and move assignment operators). Additional constructors are usually provided to increase the flexibility of the class, allowing users a variety of ways to initialise objects of the class. Constructors that accept just one argument (excluding the copy and move constructors) are regarded as being conversion constructors because, from a user's perspective, they effectively convert their argument into an object of the class. Although there is effectively no limit to the number of constructors you can define, do keep in mind the mantra that simple concepts should be expressed simply and no simpler. Make good and proper use of inline initialisation, default arguments and delegation. Use explicit constructors to avoid narrowing issues and implicit conversions where narrowing is acceptable. Also, make good use of RAII (resource acquisition is initialisation) to ensure proper cleanup should any member fail to initialise during construction. For efficiency, perform as much initialisation as possible outside the body of the constructor. Ideally, the constructor body should contain no code at all.


How can the base class data be accessed from database directly using derived class?

In order to access a base class member the base class member must be declared protected or public. Private data is only accessible to members of the same class and to friends of the class. I'm not entirely sure what you mean by accessing from a database. A derived class does not require a database in order to access its base class members, it only requires protected access at the very least. Note that although you can declare derived classes to be friends of their base classes and thus allow private access, it would be an unusual design since base classes should never know anything about any of their derivatives.


How can you justify the use of constructor and destructor in c plus plus?

Constructors allow class designers to initialise class attributes at the point of instantiation (whenever an object of the class is created). All classes must have at least one constructor other than the copy and move constructors otherwise it would be impossible to instantiate objects of the class. Copy and move constructors are not required but are generated automatically by the compiler unless the class designer explicitly marks them deleted from the class definition. The copy and move constructors allow new instances to be constructed from existing instances. The only difference between the two is that the move constructor transfers ownership of the member attributes, rather than merely copying them. In classes that contain pointers, the compiler-generated copy constructor only copies the pointer (a shallow copy) not what it points at (a deep copy). Thus class designers must provide a copy constructor in order to deep copy any unshared memory resources. Derived class constructors automatically invoke base class constructors, so classes are always constructed from the bottom up. Copy and move constructors automatically invoke their base class copy and move constructors, respectively, however all other constructors automatically invoke their base class default constructors, which may not be the most efficient method of construction. Thus class designers can invoke specific base class constructors through the constructor's own initialisation list (which is also used to initialise member attributes). Constructor bodies do not require any code except in those cases where initialisation is not possible with the initialisation list alone, however this is usually an indication of poor design choices rather than a limitation of the initialisation list. The initialisation list provides the most efficient mechanism for class initialisation. Every class must have one (and only one) destructor. If one is not provided by the class designer, the compiler generates one for you. However, unless the class contains a pointer to unshared memory, there is no need to define your own. Otherwise you must provide a destructor in order to release the memory. The destructor is the last chance to do so before an object of the class falls from scope. Classes that are intended to act as base classes must provide a virtual destructor (that is, the lowest base class must declared the destructor virtual). This ensures that if an object is destroyed polymorphically (via a pointer to one of its base classes), the most-derived destructor is always invoked first. Destruction of hierarchies is always top down. Note that destructors are not virtual by default for the simple reason that not all classes are intended to act as base classes. The containers provided by the Standard Template Library (STL) are a good example of this as none of the containers have virtual destructors -- so they cannot be used as base classes. Note that if any class method is declared virtual, the destructor must also be declared virtual. However, when inheriting from a base class with a virtual destructor, the class destructor is implicitly virtual (as are all virtual functions inherited from base classes) and does not need to be specified, although its good practice to explicitly include it anyway.


What are the properties of class in c plus plus?

A constructor is not a function. A function is a type, as specified by its return type, and must return a value of that type unless the type is void. A constructor does not return anything, not even void. The purpose of a constructor is to both allocate and initialise memory for an object of the type being constructed. If a valid object cannot be constructed for any reason, the constructor must throw an exception. If the object's class has no data members (attributes), the class does not require a constructor. This is typically the case for most abstract data types and base classes which are used purely as interfaces. Constructors differ from functions in that all constructors have an initialisation section that is used specifically to initialise non-static data members. The body of the constructor is rarely used except to perform initialisations that cannot be more easily performed by the initialisation section. A class may have more than one constructor to provide alternative methods of construction based upon the number and type of arguments supplied (if any). When no arguments are required or all arguments have default values then the constructor is known as the default constructor. If the constructor has only one argument the constructor is known as a conversion constructor (because the argument is converted to an object of the class). However, if the constructor argument is a constant reference to an object of the same class, then it is known as a copy constructor, and when the constructor argument is an rvalue reference, it is known as a move constructor. If copy and/or move constructors are provided for a class, the equivalent assignment operators should also be provided for that class. All other constructors are known as user-defined constructors.


Explain how a private data of a base class can be accessed by publicly derived class?

The only way that private attributes of a base class can be accessed by a derived class (protected or public) is through a protected or public method in the base class. The protected or public method is the interface through which access to the attributes is defined and controlled.

Related questions

How many constructors may be defined for a class?

As many as are required for the class to function. All classes other than static classes require at least one constructor. Most classes will also provide copy and move constructors (with corresponding copy and move assignment operators). Additional constructors are usually provided to increase the flexibility of the class, allowing users a variety of ways to initialise objects of the class. Constructors that accept just one argument (excluding the copy and move constructors) are regarded as being conversion constructors because, from a user's perspective, they effectively convert their argument into an object of the class. Although there is effectively no limit to the number of constructors you can define, do keep in mind the mantra that simple concepts should be expressed simply and no simpler. Make good and proper use of inline initialisation, default arguments and delegation. Use explicit constructors to avoid narrowing issues and implicit conversions where narrowing is acceptable. Also, make good use of RAII (resource acquisition is initialisation) to ensure proper cleanup should any member fail to initialise during construction. For efficiency, perform as much initialisation as possible outside the body of the constructor. Ideally, the constructor body should contain no code at all.


What religions require members to marry a person within their own faith?

Most religions require their members to marry within their own faith: the Jews, Catholics, Muslims, etc.


What is overloaded constructor in oop?

Overloading a function simply means providing the same function name with different argument types. Class constructors are no different. In fact, even if you declare no constructors in a class, there will be two compiler-generated constructor overloads provided for you: a default constructor; and a copy constructor. If you declare any other constructors, the compiler-generated default constructor will no longer be generated. You must declare your own default constructor if you require one. The copy constructor is always generated, however the default implementation only performs a member-wise copy of the class members. If your class contains a pointer to allocated memory you must provide your own copy constructor to perform a deep-copy of those pointers, so each instances "owns" its own copy of the memory.


How is reusability supported by inheritance in C Plus Plus?

Inheritance is the notion that a derived class inherits all the public and protected members of its base class. In other words, we are re-using the existing code in the base class; we need only add the specific overrides required to provide the more specialised behaviour we require of the derived class. Without inheritance, we'd have to write duplicate code in order to cater for the base class functionality we require in our derivatives, and duplicate code adds to the maintenance burden.


What does decimal mean in math?

A decimal number is simply a way of representing a number in such a way that the place value of each digit is ten times that of the digit to its right. If it does not contain a fractional part then the decimal representation does not require a decimal point. The name is derived from "deci" which means pertaining to ten.


How does a kit fox get water?

They may not require a source of drinking water. Sustains itself on moisture derived from prey.


How do potential shareholders use accounting information?

The shareholders require information on the value of their investment and income that is derived from their shareholding.


Which mineral do objects that require heat insulation usually contain?

I think that it is Mica


Does the baptist faith require partial income of followers?

No the baptist faith does NOT require a partial amount of any followers or members income.


How can the base class data be accessed from database directly using derived class?

In order to access a base class member the base class member must be declared protected or public. Private data is only accessible to members of the same class and to friends of the class. I'm not entirely sure what you mean by accessing from a database. A derived class does not require a database in order to access its base class members, it only requires protected access at the very least. Note that although you can declare derived classes to be friends of their base classes and thus allow private access, it would be an unusual design since base classes should never know anything about any of their derivatives.


Why you require constructor in cpp?

Constructors are not a requirement of CPP. A default constructor and copy constructor are automatically generated by the compiler for every class you create when no constructors are declared. The only time you need to declare a constructor is when you wish to override the default behaviour of the generated constructors, to ensure the class is correctly initialised. When any constructor is declared, the default constructor is no longer generated by the compiler -- you must define your own default constructor (one that has no parameters, or where all the parameters have default values). The copy constructor is always generated for you regardless of how many other constructors you declare. But if the class contains pointers to allocated memory that is "owned" by the class then you must override the generated copy constructor with your own copy constructor. This is to ensure the memory is deep copied (the generated copy constructor only performs a shallow, member-wise copy of the members). Otherwise two objects of the same class will end up pointing at the same memory, which would be disastrous if either one were to be deleted. The other instance would be automatically invalidated because it would point to memory that was released by the other instance's destructor.


How can primary caregivers and family members be assisted to care for LBD patients?

Primary caregivers and family members require information concerning management of symptoms such as hallucinations, agitation, and cognitive changes. Children of patients with LBD may require genetic counseling.