helmet91
helmet91

Reputation: 127

How to make child class interchangeable with parent class in C++?

I am trying to do a C++ exercise, which consists of a test code (main.cpp) and a header file (vcvec.h). The test code supposed to remain untouched, whereas the included header file should satisfy the test code (this is what I have to write from scratch).

In this exercide I have to write an extension to the std::vector by inheritance. I managed to solve most parts of this exercise, now, I will attach below only the relevant part of the code.

main.cpp (test code)

#include <string>
#include "vcvec.h"

int main()
{
    version_controlled_vector<unsigned int> v;
    version_controlled_vector<std::string> a;

    v.push_back( 1 );
    a.push_back("C++");

    std::vector<std::vector<std::string> > hista = a;
    std::vector<std::vector<int> > histv = v;
}

vcvec.h

#ifndef VCVEC_H
#define VCVEC_H

#include <vector>

template<class T>
class version_controlled_vector : public std::vector<T>
{
private:
    std::vector<std::vector<T>> history;
};

#endif // VCVEC_H

This code generates the following compile errors:

main.cpp: In function ‘int main()’:
main.cpp:12:52: error: conversion from ‘version_controlled_vector<std::basic_string<char> >’ to non-scalar type ‘std::vector<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > >, std::allocator<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > > >’ requested
     std::vector<std::vector<std::string> > hista = a;
                                                    ^
main.cpp:13:44: error: conversion from ‘version_controlled_vector<unsigned int>’ to non-scalar type ‘std::vector<std::vector<int> >’ requested
     std::vector<std::vector<int> > histv = v;
                                            ^

How can I assign an instance of version_controlled_vector to an std::vector type? The only solution I can think of, is an appropriate copy-constructor, but it should take place in the std::vector class, so it is not an option.

Upvotes: 1

Views: 206

Answers (1)

R Sahu
R Sahu

Reputation: 206607

These are the options I can think of:

  1. Provide a function that returns a reference to the private data.

    template<class T>
    class version_controlled_vector : public std::vector<T>
    {
        std::vector<std::vector<T>> const& getHistory() {return history;} const
      private:
        std::vector<std::vector<T>> history;
    };
    

    Then, in the client code, use:

    std::vector<std::vector<std::string> > hista = a.getHistory();
    
  2. Provide an auto cast operator function

    template<class T>
    class version_controlled_vector : public std::vector<T>
    {
      public:
        operator std::vector<std::vector<T>> const& () {return history;} const
      private:
        std::vector<std::vector<T>> history;
    };
    

    Then, in the client code, use:

    std::vector<std::vector<std::string> > hista = a;
    
  3. Make the data public so others can use directly (Not recommended)

    std::vector<std::vector<std::string> > hista = a.history;
    

Update, in response to comment by OP

I am not sure how your files look like, but the following code, when put in one .cc file, compiles and builds for me.

#include <vector>

template<class T>
class version_controlled_vector : public std::vector<T>
{
   public:

      operator std::vector<std::vector<T> > const& () {return history;}

   private:

    std::vector<std::vector<T> > history;
};

#include <string>

int main()
{
    version_controlled_vector<unsigned int> v;
    version_controlled_vector<std::string> a;

    v.push_back( 1 );
    a.push_back("C++");

    std::vector<std::vector<std::string> > hista = a;
    std::vector<std::vector<unsigned int> > histv = v;
}

Upvotes: 3

Related Questions