Caroline Beltran
Caroline Beltran

Reputation: 918

Create subclass of class template

The following working code displays the smaller of two given numbers.

#include "stdafx.h"
#include <iostream>
using namespace std;

template <class T>
class Bucky {
public:
  Bucky(T a, T b) {
    first  = a;
    second = b;
  }
  T smaller() {
    return (first<second?first:second);
  }
private:
  T first, second;
};


int main() {
  Bucky <int>obj(69, 105);
  cout << obj.smaller() << endl;
  return 0;
}

I would like to derive from class 'Bucky' and create a subclass having a member function that displays "Hi There!"

Please help.

P.S. Here is my best failed attempt to create my subclass:

template <class T>
class mySubclass : public Bucky<T>
{
public:
  mySubclass(T a, T b) {  // error C2512: 'Bucky<T>' : no appropriate default constructor available
    //first  = a;
    //second = b;
  }
  void greet() {
    cout << "Hi there!";
  }
};

Upvotes: 3

Views: 4972

Answers (5)

Joseph Mansfield
Joseph Mansfield

Reputation: 110658

When you construct a derived class, it will also construct its base class. If you don't explicitly specify this, it will attempt to construct the base class using its default constructor (with no arguments). However, your base class doesn't have a default constructor. Instead, you want to delegate to the constructor of Bucky that takes two T arguments:

mySubclass(T a, T b)
  : Bucky<T>(a, b) { }

As you can see, this uses a strange syntax beginning with : and leaves the constructor body empty. This syntax is the member initialization list. It says that we're initialising the Bucky<T> base class by passing a and b to its constructor. In fact, you should also use this for your Bucky constructor:

Bucky(T a, T b)
  : first(a), second(b) { }

Here we are initialising the first and second members with a and b respectively.

Upvotes: 4

Will Custode
Will Custode

Reputation: 4594

You can call the base constructor from the derived constructor as such:

mySubClass(T a, T b)
    : Bucky(a, b)
{
}

As the error states, by implementing a constructor (one that accepts arguments) you have removed the default constructor. And when you create a constructor for a subclass it must initialize its base class. The way to do this is to call the base constructor in the initializer list, as someone in the comments mentioned.

Upvotes: 1

Aumnayan
Aumnayan

Reputation: 669

template <class T>
class a:public Bucky<T> {
public:
  a(T r, T l): Bucky<T>(r, l) {}
  void Hello(void) { std::cout << "Hello there!" << std::endl; }
};

int main() {
  Bucky <int>obj(69, 105);
  a<int> obj2(69, 105);

  obj2.Hello();
  cout << obj.smaller() << endl;
  return 0;
}

I think this get's you what you're looking for.

Upvotes: 0

Praetorian
Praetorian

Reputation: 109119

The mySubclass constructor does not explicitly initialize the base class object Bucky. So the compiler will attempt to do so implicitly by calling the default constructor for Bucky. As the error says, Bucky does not have a default constructor. To fix the error, initialize Bucky explicitly in the contructor's member initializer list.

mySubclass(T a, T b)
: Bucky<T>(a, b)
{}

You should also use the member initializer list to initialize Bucky's data members

Bucky(T a, T b) 
: first(a)
, second(b)
{}

Upvotes: 3

Lemming
Lemming

Reputation: 4205

As the compiler points out, it cannot find an appropriate default constructor for your base class. So, you need to call one explicitely in the member initializer list.

template <class T>
class mySubclass : public Bucky<T>
{
public:
  mySubclass(T a, T b) : Bucky<T>(a, b) { }
  void greet() {
    cout << "Hi there!";
  }
};

Upvotes: 1

Related Questions