Друг класса C++

Я пытаюсь скомпилировать такой код:

#include <iostream>
using namespace std;

class CPosition
{
  private:
    int itsX,itsY;
  public:
    void Show();
    void Set(int,int);
};

void CPosition::Set(int a, int b)
{
  itsX=a;
  itsY=b;
}

void CPosition::Show()
{
    cout << "x:" << itsX << " y:" << itsY << endl;
}

class CCube
{
  friend class CPosition;
  private:
         CPosition Position;
};

main()
{
  CCube cube1;

  cube1.Position.Show();
  cube1.Position.Set(2,3);
  cube1.Position.Show();
}

но получить 'CCube :: Position' невозможно в функции main () 3 раза. Я хочу, чтобы класс CPosition был объявлен вне CCube, чтобы я мог использовать его в будущем в новых классах, например. CBall :) но как заставить его работать без наследования. Является ли это возможным :)?

С уважением, ПК

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
2 298
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

ошибка, нет, позиция не отображается в функции "main"

Сделайте его общедоступным ... или поместите в

Оператор friend class CPosition; означает, что CPosition теперь может получить доступ к закрытым членам класса CCube. Для каждого другого класса члены остаются такими же частными, как вы их объявили. Чтобы образец заработал, вам нужно:

class CCube
{
     public:
         CPosition Position;
};

Что ж, вы уже получили ответ на ошибку. Одно но: Планируете ли вы, что куб будет иметь доступ к закрытым членам CPosition (itsX, itsY)? В противном случае его не нужно объявлять другом. Если это так, рассмотрите возможность предоставления общедоступных методов в CPosition для возврата X и Y, и вам все равно не нужно объявлять его как друга.

Я говорю о том, что вам нужно убедиться, что вам нужно использовать друзей. Вот хорошее место для начала.

Объявление вашего друга должно быть

friend int main();

Вы даете «основное» разрешение на доступ к закрытому члену CCube.

Хорошо, это работает с:

class CCube
{
  private:
         CPosition Position;
  public:
  CPosition& getPosition() { return Position; }
};

main()
{
  CCube cube1;

  cube1.getPosition().Show();
  cube1.getPosition().Set(2,3);
  cube1.getPosition().Show();
}

Спасибо

Это определенно работает, но это не значит, что это лучшая идея. Может быть, лучше, например, добавьте SetPosition (x, y) в CCube, который вызывает сам Position.Set (x, y), таким образом вы лучше скрываете внутреннюю часть CCube. По сути, добавление общедоступных функций для тех частей Position, которые вам нужны.

Pieter 31.10.2008 18:10

У вас 3 вопроса в одном:

  1. возможность повторного использования CPosition
  2. как влиять на состояние фигуры (в данном случае включает член типа CPosition, но также может включать в себя int radius или что-то еще)
  3. Использование ключевого слова friend

Вы четко говорите, что вам нужно, чтобы класс CPosition был доступен из других мест. Что ж, классно. Проблема 1 решена.

Если вы хотите, чтобы пользователи CCube могли изменять положение CCube, вам необходимо предоставить средства для этого:

  1. Сделав CCube::Position общедоступным
  2. Добавив методы доступа - CCube::MoveTo( const CPosition& p ) и CCube::GetPosition() const.

Как сказал @Firas: не играйте с friend, пока не убедитесь, что он вам нужен.

Ответ принят как подходящий

В дополнение к обычному геттеру у вас также должен быть константный геттер. Обратите внимание на возврат по ссылке. Это позволяет любому вызову SetXX () воздействовать на копию Position внутри CCube, а не на копию, которую вы обновляете.

class CCube
{
    private:
        CPosition Position;
    public:
        CPosition&       getPosition()       { return Position; }
        CPosition const& getPosition() const { return Position; }
};

Другие вопросы по теме