Попробуйте передать объект в тот же класс шаблона для копирования - PullRequest
0 голосов
/ 01 апреля 2020

Я работаю над тем, чтобы понять концепцию шаблона и реализовать простую. Мне удается почти во всех случаях, кроме одного, чтобы написать конструктор, чтобы скопировать экземпляр того же класса.

#include <iostream>

// template <typename T>
template <class T>
class vec2 {
private:
    static int instance;
    T const x;
    T const y;
public:
    vec2() : x(0), y(0) {
        std::cout << "Default constructor" << std::endl;
        vec2<T>::instance++;
        return;
    }

    vec2(T const &x, T const &y) : x(x), y(y) {
        std::cout << "Parametric constructor" << std::endl;
        vec2<T>::instance++;
        return;
    }

    vec2(vec2<T> const & src) {
        *this = src;
        std::cout << "Copy constructor" << std::endl;
        vec2<T>::instance++;
        return;
    }

    ~vec2(){
        std::cout << "Destructor" << std::endl;
        vec2<T>::instance--;
        return;
    }

    vec2 & operator=(vec2 const & rhs) {
        this->x = rhs.get_x();
        this->y = rhs.get_y();
        return *this;
    }

  // get
    static int get_instance() {
        return vec2<T>::instance;
    }

    T get_x() const {
        return this->x;
    }

    T get_y() const {
        return this->y;
    }
}; 

template <class T>
std::ostream & operator<<(std::ostream & out, vec2<T> const & rhs) {
    out << "[ " << rhs.get_x() << ", " << rhs.get_y() << " ]";
    return out;
}

template <class T>
int vec2<T>::instance = 0;


int main() {
    vec2<float> a;
    vec2<int> b(21, 42);
    vec2<float> c(21.21f, 42.42f);
    vec2<bool> d(true, false);
    vec2<int> e(b);

    std::cout << a << std::endl;
    std::cout << b << std::endl;
    std::cout << c << std::endl;
    std::cout << d << std::endl;
    std::cout << e << std::endl;

    std::cout << "a.get_x(): " << a.get_x() << std::endl;
    std::cout << "a.get_y(): " << a.get_y() << std::endl;

    std::cout << "b.get_x(): " << b.get_x() << std::endl;
    std::cout << "b.get_y(): " << b.get_y() << std::endl;

    std::cout << "c.get_x(): " << c.get_x() << std::endl;
    std::cout << "c.get_y(): " << c.get_y() << std::endl;

    std::cout << "d.get_x(): " << d.get_x() << std::endl;
    std::cout << "d.get_y(): " << d.get_y() << std::endl;

    return (0);
}

здесь сообщение об ошибке, но я не эксперт, чтобы прочитать его, и я не понимаю, что я должен изменить свой код Так что если у кого-то есть идея помочь новичку в C ++, это может быть здорово.

clang++  -std=c++11 -Wconversion *.cpp && ./a.out
main.cpp:24:2: error: constructor for 'vec2<int>' must explicitly initialize the
      const member 'x'
        vec2(vec2<T> const & src) {
        ^
main.cpp:72:12: note: in instantiation of member function 'vec2<int>::vec2'
      requested here
        vec2<int> e(b);
                  ^
main.cpp:9:10: note: declared here
        T const x;
                ^
main.cpp:24:2: error: constructor for 'vec2<int>' must explicitly initialize the
      const member 'y'
        vec2(vec2<T> const & src) {
        ^
main.cpp:10:10: note: declared here
        T const y;
                ^
main.cpp:38:11: error: cannot assign to non-static data member 'x' with
      const-qualified type 'const int'
                this->x = rhs.get_x();
                ~~~~~~~ ^
main.cpp:25:9: note: in instantiation of member function 'vec2<int>::operator='
      requested here
                *this = src;
                      ^
main.cpp:72:12: note: in instantiation of member function 'vec2<int>::vec2'
      requested here
        vec2<int> e(b);
                  ^
main.cpp:9:10: note: non-static data member 'x' declared const here
        T const x;
        ~~~~~~~~^
main.cpp:39:11: error: cannot assign to non-static data member 'y' with
      const-qualified type 'const int'
                this->y = rhs.get_y();
                ~~~~~~~ ^
main.cpp:10:10: note: non-static data member 'y' declared const here
        T const y;
        ~~~~~~~~^
4 errors generated.

Ответы [ 2 ]

2 голосов
/ 01 апреля 2020

Как сказал @Sam Varshavchik в комментариях, проблема в том, что вы не инициализируете свои const члены в вашем конструкторе копирования. Вот правильная реализация:

vec2(vec2<T> const & src) : x(src.get_x()), y(src.get_y()) { //<-- initialization of const members
    std::cout << "Copy constructor" << std::endl;
    vec2<T>::instance++;
    return;
 }

Кроме того, *this = src; чувствует все виды ошибок.

0 голосов
/ 01 апреля 2020

здесь мой оригинальный код класса, где я делаю копию с *this = src, и результат отлично работает. Итак, вопрос, почему это работает с обычным class, а не с template? Плюс я представляю поведение с обычным классом, адрес остается прежним. И способ инициализации всех членов может быть сложным, если много членов переменных в классе? main.c

#include "Vec2.hpp"
#include <iostream>

int main() {
    Vec2 a;
    Vec2 b(21,42);
    Vec2 c(a);

    std::cout << a << std::endl;

    std::cout << "c.get_x(): " << c.get_x() << std::endl;
    std::cout << "c.get_y(): " << c.get_y() << std::endl;

    std::cout << "b.get_x(): " << b.get_x() << std::endl;
    std::cout << "b.get_y(): " << b.get_y() << std::endl;

    std::cout << "a.get_x(): " << a.get_x() << std::endl;
    std::cout << "a.get_y(): " << a.get_y() << std::endl;
    a = b;
    std::cout << "a.get_x(): " << a.get_x() << std::endl;
    std::cout << "a.get_y(): " << a.get_y() << std::endl;
    return 0;
}

Vec2.cpp

#ifndef VEC2_H
# define VEC2_H

#include <iostream>

class Vec2 {
public:
    Vec2(); // canonical
    Vec2(float const x, float const y);
    Vec2(Vec2 const &); // canonical
    ~Vec2();    // canonical

    Vec2 & operator=(Vec2 const & rhs);     // canonical

    static int get_instance();

    float get_x() const ;
    float get_y() const ;

private:
    static int instance;
    float x;
    float y;
}; 

std::ostream & operator<< (std::ostream & out, Vec2 const & rhs);

#endif

vec2.hpp

#include "Vec2.hpp"
#include <iostream>

Vec2::Vec2() : x(0), y(0) {
    std::cout << "Default constructor" << std::endl;
    Vec2::instance++;
    return;
}

Vec2::Vec2(float const x, float const y) : x(x), y(y) {
    std::cout << "Parametric constructor" << std::endl;
    Vec2::instance++;
    return;
}

Vec2::Vec2(Vec2 const & src) {
    *this = src;
    std::cout << "Copy constructor" << std::endl;
    Vec2::instance++;
    return;
}

Vec2::~Vec2() {
    std::cout << "Destructor" << std::endl;
    Vec2::instance--;
    return;
}

Vec2 & Vec2::operator=(Vec2 const & rhs) {
    this->x = rhs.get_x();
    this->y = rhs.get_y();
    return *this;
}

int Vec2::get_instance(){
    return Vec2::instance;
}

float Vec2::get_x() const {
    return this->x;
}

float Vec2::get_y() const {
    return this->y;
}

std::ostream & operator<< (std::ostream & out, Vec2 const & rhs) {
    out << "[ " << rhs.get_x() << ", " << rhs.get_y() << " ]";
    return out;
}


int Vec2::instance = 0;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...