Область применения класса и частные члены?
Я определяю функцию для добавления элементов в vector<Point> original_points
по имени void add_point()
, Почему стоит выделить original_points
как неопределенное, в теле функции, когда я использую квалификатор типа: friend (чтобы получить доступ), и это находится в области видимости класса?
// data structure representing Point in 2D plane
class Point{
public:
//contructors
Point();
Point(double x, double y);
// non-modifying methods
inline double get_xcoord()const{return xcoord;}
inline double get_ycoord()const{return ycoord;}
// modifying methods
inline double set_xcoord(double x){xcoord=x;}
inline double set_ycoord(double y){ycoord=y;}
// non-member function with access to private members
friend inline void add_point(const Point& p){original_points.push_back();}
private:
double xcoord;
double ycoord;
vector<Point> original_points;};
Что я делаю неправильно?
5 ответов
Друг не является функцией-членом, поэтому он не может получить доступ к нестатическим членам напрямую; это будет нужно Point
объект действовать Вы также должны передать что-то push_back
,
Неясно, является ли параметр функции p
должен быть объектом для доступа, объектом для передачи push_back
, или оба; или действительно ли это должен быть участник, а не друг. Последнее кажется более вероятным - вы, вероятно, хотите:
void add_point(const Point& p){original_points.push_back(p);}
Там как минимум три основные проблемы:
Во-первых, std::vector::push_back()
имеет параметр. Вам нужно пройти Point
пример этому. Кажется, вы хотите добавить p
:
original_points.push_back(p);
Во-вторых, функция Friend не является членом, поэтому вы не можете получить доступ к членам класса через нее без экземпляра этого класса. У вас нет такого экземпляра, поэтому функция вашего друга не имеет смысла. Это скомпилирует, но не будет иметь никакого эффекта:
friend
inline void add_point(const Point& p){
Point x;
x.original_points.push_back(p);
}
Возможно, вы хотели add_point()
быть членом, в этом случае это не должно быть friend
, Это решило бы вторую проблему, но...
В-третьих, предполагая, original_points
является std::vector<Point>
такие контейнеры не могут быть созданы с неполным типом. Так Point
не может иметь член данных std::vector<Point>
без вызова неопределенного поведения. Если с другой стороны, это было boost::container::<Point>
, или другой vector
это поддерживает неполные типы, это было бы хорошо.
В целом, ваш код выглядит довольно испорченным.
Друзья получают доступ к закрытым частям класса. Но это не проблема - функция все еще не является членом (если бы она была членом, она не должна была бы быть другом). Функция нуждается в объекте для доступа к нестатическим членам этого объекта. То, что у вас есть, в основном так же, как это:
class Point
{
public:
vector<Point> original_points;
};
void add_point(const Point &p) { original_points.push_back(p); }
Здесь нет original_points
за add_point
ссылаясь на.
Либо ты хотел original_points
быть static
или вам придется пройти Point
возражать в add_point
чтобы получить доступ к его original_points
член или доступ к нему на p
,
Как примечание стороны, push_back()
принимает один аргумент - вы должны указать, что добавить к вектору (но я предполагаю, что это должно быть p
).
Как вы говорите, вы хотите добавить элемент типа Point к вектору, в котором хранятся элементы строкового типа, поэтому вы можете также иметь ошибку несоответствия типов. Но для undefined у меня была та же ошибка, и оказалось, что она была вызвана строковым типом, когда вы используете строку, вы должны упомянуть, что вы используете строку из стандартной библиотеки, поэтому я добавил "using namespace std;" и ошибка ушла. Это может помочь вам также.
Мысль о том, чтобы положить vector<Point>
а также add_point(const Point& p)
внутри класса должна была быть какая-то местность. Поставить тогда под общее namespace
должно быть лучшее решение (?)
namespace MyPoint{
// data structure representing Point in 2D plane
class Point{
public:
//contructors
Point();
Point(double x, double y);
// non-modifying methods
inline double get_xcoord()const{return xcoord;}
inline double get_ycoord()const{return ycoord;}
// modifying methods
inline double set_xcoord(double x){xcoord=x;}
inline double set_ycoord(double y){ycoord=y;}
private:
double xcoord;
double ycoord;};
vector<Point> original_points;
void add_point(const Point& p){original_points.push_back(p);} //end of namespace