尝试将对象传递给同一个模板类进行复制
Posted
技术标签:
【中文标题】尝试将对象传递给同一个模板类进行复制【英文标题】:Try to pass an object to a same template class to copy 【发布时间】:2020-04-01 15:19:09 【问题描述】:我实际上是为了理解模板的概念并实现一个简单的模板。我几乎设法编写一个构造函数来复制同一类的实例。
#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.
【问题讨论】:
这与模板无关。如果您声明一个带有const
类成员的常规类,并且您的构造函数无法初始化它,您将得到同样的错误。 “*this = src;
”将不起作用。 x 和 y 必须在初始化部分显式构造。有关详细信息,请参阅您的 C++ 书籍。
【参考方案1】:
正如@Sam Varshavchik 在 cmets 中所说,问题在于您没有在复制构造函数中初始化 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;
确实感觉各种不对劲。
【讨论】:
【参考方案2】:这里是我的原始课程代码,我用*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;
【讨论】:
问题不在于常规类和模板类。在此实现中,您的x
和y
成员不是const
。让他们const
你会得到同样的错误。此外,*this = src
将调用(默认定义的)复制赋值运算符,这就是它可能起作用的原因,但这不是你应该这样做的原因。
这就是所有这些信息。我使用这种方法是因为在 42 学校的 tutovideo 中,老师使用这种方法,但可能并不是真正的最佳方法。谢谢你的灯。以上是关于尝试将对象传递给同一个模板类进行复制的主要内容,如果未能解决你的问题,请参考以下文章
Vaadin 12将对象传递给JavaScript的函数:不能编码类