在派生 class 中包装私有容器的运算符 [ ]
Wrapping an operator[ ] of a private container in derived class
我正在尝试实现一个名为:Shape& move_up(int index)
的包装函数,它将在派生的 [=] 中访问和修改 vector<T*> v
的 1 个元素50=],命名为:class Group
。
我正在尝试通过包裹基数 class:
的 T& operator[](int i) { return *v[i]; }
来做到这一点
Group.h
:
// class Group is a container of Shapes
class Group: public Graph_lib::Vector_ref<Shape>{
public:
// constructors
Group::Group()
: upperLeft(0, 0), gridSideX(50), gridSideY(50), gridRowNumber(5), gridColumnNumber(5)
{
// create grid
for (size_t i = 0; i <= gridRowNumber; ++i){
for (size_t j = 0; j <= gridColumnNumber; ++j){
Graph_lib::Rectangle* rec = new Graph_lib::Rectangle(Point(upperLeft.x + gridSideX * j, upperLeft.y + gridSideY * i), gridSideX, gridSideY);
rec->set_fill_color(((i + j) % 2 == 0) ? Color::black : Color::white);
push_back(rec);
}
}
}
Shape& move_up(int i) { return operator[](i).move(0, 70); }
private:
Point upperLeft;
int gridSideX;
int gridSideY;
int gridRowNumber;
int gridColumnNumber;
};
main.cpp
#include <iostream>
#include <vector>
#include "Graph.h"
#include "Simple_window.h"
#include "Group.h"
int main(){
// define a window
Point tl(x_max()/2,0);
int width = 700;
int height = 700;
string label = "class Group";
Simple_window sw(tl, width, height, label);
// instantiate a class Group object
Group gr();
for (size_t i = 0; i < gr.size(); ++i) sw.attach(gr[i]);
sw.wait_for_button();
}
目前包装函数有红色下划线,当悬停在上面时会显示以下消息:
Error: initial value to reference to non-const must be an lvalue
问题是我找不到访问和修改基class向量中元素的正确方法,因此出现以下问题:
我做错了什么?如何正确实现Shape& move_up(int index);
功能?
1.应用函数 move();
更改向量的 Shape
元素的坐标。
你的函数 move()
returns void
:
virtual void move(int dx, int dy);
当您尝试让 move_up()
return 成为 move()
的 结果 时,您期望什么:
return <something>.move(0, 70);
特别是你之前告诉编译器 move_up()
应该 returns Shape&
?
函数 move_up()
必须:
- 修改
Shape
的坐标
- return
Shape&
这样它就可以 attache()
d 到 window 对象,并且它的新位置显示在屏幕上。
为此,它只需要分成两行,第一行修改 Shape
对象,第二行 return 通过引用修改它:
Shape& move_up(int i) {
operator[](i).move(0, 70);
return operator[](i);
}
或按照 molbdnilo 的建议:
Shape& move_up(int i) {
auto& el = (*this)[i];
el.move(0, 70);
return el;
}
我正在尝试实现一个名为:Shape& move_up(int index)
的包装函数,它将在派生的 [=] 中访问和修改 vector<T*> v
的 1 个元素50=],命名为:class Group
。
我正在尝试通过包裹基数 class:
的T& operator[](int i) { return *v[i]; }
来做到这一点
Group.h
:
// class Group is a container of Shapes
class Group: public Graph_lib::Vector_ref<Shape>{
public:
// constructors
Group::Group()
: upperLeft(0, 0), gridSideX(50), gridSideY(50), gridRowNumber(5), gridColumnNumber(5)
{
// create grid
for (size_t i = 0; i <= gridRowNumber; ++i){
for (size_t j = 0; j <= gridColumnNumber; ++j){
Graph_lib::Rectangle* rec = new Graph_lib::Rectangle(Point(upperLeft.x + gridSideX * j, upperLeft.y + gridSideY * i), gridSideX, gridSideY);
rec->set_fill_color(((i + j) % 2 == 0) ? Color::black : Color::white);
push_back(rec);
}
}
}
Shape& move_up(int i) { return operator[](i).move(0, 70); }
private:
Point upperLeft;
int gridSideX;
int gridSideY;
int gridRowNumber;
int gridColumnNumber;
};
main.cpp
#include <iostream>
#include <vector>
#include "Graph.h"
#include "Simple_window.h"
#include "Group.h"
int main(){
// define a window
Point tl(x_max()/2,0);
int width = 700;
int height = 700;
string label = "class Group";
Simple_window sw(tl, width, height, label);
// instantiate a class Group object
Group gr();
for (size_t i = 0; i < gr.size(); ++i) sw.attach(gr[i]);
sw.wait_for_button();
}
目前包装函数有红色下划线,当悬停在上面时会显示以下消息:
Error: initial value to reference to non-const must be an lvalue
问题是我找不到访问和修改基class向量中元素的正确方法,因此出现以下问题:
我做错了什么?如何正确实现Shape& move_up(int index);
功能?
1.应用函数 move();
更改向量的 Shape
元素的坐标。
你的函数 move()
returns void
:
virtual void move(int dx, int dy);
当您尝试让 move_up()
return 成为 move()
的 结果 时,您期望什么:
return <something>.move(0, 70);
特别是你之前告诉编译器 move_up()
应该 returns Shape&
?
函数 move_up()
必须:
- 修改
Shape
的坐标 - return
Shape&
这样它就可以attache()
d 到 window 对象,并且它的新位置显示在屏幕上。
为此,它只需要分成两行,第一行修改 Shape
对象,第二行 return 通过引用修改它:
Shape& move_up(int i) {
operator[](i).move(0, 70);
return operator[](i);
}
或按照 molbdnilo 的建议:
Shape& move_up(int i) {
auto& el = (*this)[i];
el.move(0, 70);
return el;
}