Constness and friendship are two completely different and unrelated things.
It doesn't matter if A is a friend of B or not. That is simply a design choice on your part whether you want to encapsulate access to the B members inside of A, or if you want to allow the caller to access B getters/setters directly.
As far as modifying an object is concerned, any getters should be declared as const so they can be called on const and non-const objects alike (since they don't modify the object they are reading from), but if you want to be able to modify the members of an object then you must access the object via a non-const pointer (or non-const reference):
class B;
class A {
private:
std::vector<B*> m_list;
public:
// this can be called on a non-const A, and
// the B members can be read and modified...
B* getB(int index) {
return m_list[index];
}
// this can be called only on a const A, and
// the B members can be read but not modified...
const B* getB(int index) const {
return m_list[index];
}
/* optional:
int getB_A(int index) const {
return getB(index)->getA();
}
float getB_B(int index) const {
return getB(index)->getB();
}
long getC(int index) const {
return getB(index)->getC();
}
void setB_A(int index, int value) {
getB(index)->setA(value);
}
void setB_B(int index, float value) {
getB(index)->setB(value);
}
void setB_C(int index, long value) {
getB(index)->setC(value);
}
*/
};
class B {
private:
int a;
float b;
long c;
public:
int getA() const {
return a;
}
float getB() const {
return b;
}
long getC() const {
return c;
}
void setA(int value) {
a = value;
}
void setB(float value) {
b = value;
}
void setC(long val) {
c = val;
}
};
Or:
class B;
class A {
private:
std::vector<B*> m_list;
public:
// this can be called on a non-const A, and
// the B members can be read and modified...
B* getB(int index) {
return m_list[index];
}
// this can be called only on a const A, and
// the B members can be read but not modified...
const B* getB(int index) const {
return m_list[index];
}
int getB_A(int index) const {
return getB(index)->a;
}
float getB_B(int index) const {
return getB(index)->b;
}
long getC(int index) const {
return getB(index)->c;
}
void setB_A(int index, int value) {
getB(index)->a = value;
}
void setB_B(int index, float value) {
getB(index)->b = value;
}
void setB_C(int index, long value) {
getB(index)->c = value;
}
};
class B {
private:
int a;
float b;
long c;
friend class A;
};
constis necessitated. "Or, I can make classAbe a friend of classB, then it can modify the private members ofBto avoid duplication of code." yeah, if you only want to be able to modify members fromAthen that's fine, and not really concretely bad practice. Your real intention is still not clear, but honestly, I imagine you're overthinking and getting confused. I could be wrong but I reckon,Bs members shouldn't beprivateat all, butpublic.