Предположим, у меня есть классы как:
namespace scope
{
class A
{
private:
int a;
public:
...
};
class B
{
public:
...
A method();
...
};
};
Определение метода:
A B::method()
{
A object;
object.a = 3; // private member access error
// access via object (pointer) error if inheritance is used
return object;
}
Наиболее распространенный способ решения ошибки доступа — использование методов установки + получения.
Однако я не хочу устанавливать какие-либо другие области (или кто-то, использующий API) A.a
так метод публичного сеттера запрещен для этого случая.
a
может быть публичным но он должен быть доступен только для чтения на стороне API. Так должно быть Чтение + запись на стороне источника, потому что, например, я хочу установить его с B::method
, Как я могу добиться этого поведения?
Я пробовал наследование, а также дружеские отношения. Я также играл с immutable
а также const
декларации о недвижимости. Проблема в том, что когда я объявляю объект с конструктором по умолчанию, для свойства устанавливается какое-то значение, например -918316838410 (которое может возникнуть из-за того, что я не использую extern
Я не уверен) и не может быть установлен method
позже.
Любые идеи будут оценены. Заранее спасибо.
Вы хотите, чтобы B имел доступ к A, чего не хотите иметь другие люди?
Это дружба.
добавлять friend class B
в определение класса А, и все будет счастье.
Кстати, общие примеры для этого, когда я использую несколько классов для создания одного интерфейса. Например, такие вещи, как список<> и карта<> обычно нужны классы узлов, и эти классы часто хотят иметь доступ друг к другу. Это нарушение инкапсуляции прекрасно, так как с логической точки зрения это действительно один большой класс.
Имейте в виду, что большинство людей должны использовать друзей редко или никогда, в основном это для авторов библиотек, а не для общего программирования.
Как сказал Ричард, ты можешь использовать дружбу. Но имейте в виду, что когда вам нужна дружба, вы, вероятно, должны снова подумать о своем дизайне. Как сказал и Ричард, возможно, использование в качестве параметра конструктора A должно делать именно то, что вы хотите.
Вот рабочий пример с дружбой:
#include <iostream>
namespace scope
{
class A{
friend class B;
private:
int a;
public:
void print(){
std::cout << a << std::endl;
}
};
class B{
public:
A method(){
A a;
a.a=3;
return a;
}
};
int main(){
scope::B b;
scope::A a = b.method();
a.print(); //just to see it works...
}
Вот способ сделать то же самое без дружбы и частной жизни (хорошо, это уродливо 🙂
#include <iostream>
namespace scope
{
class B;
class A
{
private:
int a;
public:
void print(){
std::cout << a << std::endl;
}
// A way to only allow B instances to give a correct value
// of "a" member
void pleaseClassBSetMyPrivateMember(B& b);
};
class B
{
public:
A method(){
A a;
a.pleaseClassBSetMyPrivateMember(*this);
return a;
}
int computeValueForMemberOfClassA(A& a){
// you can access public members of a to
// calculate the proper value of a.a member
return 3;
}
};
void A::pleaseClassBSetMyPrivateMember(B& b)
{
// ask for class B object the correct value for member a
a = b.computeValueForMemberOfClassA(*this);
}
};