Область применения класса и частные члены?

Я определяю функцию для добавления элементов в 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
Другие вопросы по тегам