Как сделать дочерний класс взаимозаменяемым с родительским классом в C ++?

Я пытаюсь сделать упражнение C ++, которое состоит из тестового кода (main.cpp) и заголовочный файл (vcvec.h). Тестовый код должен остаться без изменений, тогда как включенный заголовочный файл должен соответствовать тестовому коду (это то, что я должен написать с нуля).

В этом упражнении я должен написать расширение std :: vector по наследству. Мне удалось решить большинство частей этого упражнения, теперь я прикреплю ниже только соответствующую часть кода.

main.cpp (тестовый код)

#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

Этот код генерирует следующие ошибки компиляции:

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;
^

Как я могу назначить экземпляр version_controlled_vector типу std :: vector? Единственное решение, о котором я могу подумать, — это соответствующий конструктор копирования, но он должен иметь место в классе std :: vector, поэтому это не вариант.

1

Решение

Вот варианты, которые я могу придумать:

  1. Предоставьте функцию, которая возвращает ссылку на личные данные.

    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;
    };
    

    Затем в коде клиента используйте:

    std::vector<std::vector<std::string> > hista = a.getHistory();
    
  2. Обеспечить функцию оператора автоматического приведения

    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;
    };
    

    Затем в коде клиента используйте:

    std::vector<std::vector<std::string> > hista = a;
    
  3. Сделать данные public так что другие могут использовать напрямую (не рекомендуется)

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

Обновление, в ответ на комментарий от OP

Я не уверен, как выглядят ваши файлы, но следующий код, помещенный в один файл .cc, компилируется и собирается для меня.

#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;
}
3

Другие решения


По вопросам рекламы ammmcru@yandex.ru