0

I have a class A with a member that is a std::vector of pointers to objects of another class B. My class returns a const pointer to an object at a particular index. Now, if I want to modify the object, what is the best way of doing that?

I can write get/set methods in class A, which will eventually use get/set methods of class B, but it is a duplication of code. Is it good practice to modify the private members by using the friend keyword?

Or, I can make class A be a friend of class B, then it can modify the private members of B to avoid duplication of code.

Or, I can remove the const on the returned pointer.

class B;

class A {
    std::vector<B*> m_list;
public:
    const B* getB(int index) {
        return m_list[index];
    }
};

class B {
private:
    int a;
    float b;
    long c;

    long getC() {
        return C;
    }

    int getA() {
        return a;
    }

    float getB() {
        return b;
    }

    /*
    set_methods
    */
};
6
  • 4
    It's not entirely clear what you're asking, are you able to produce a code minimal reproducible example to illustrate your question? Commented Jun 14, 2017 at 18:47
  • 3
    "Is it good practice to modify the private members by using the friend keyword?" - No. Commented Jun 14, 2017 at 19:04
  • 1
    "I can remove the const on the returned pointer" - this is even worse than "friend". Commented Jun 14, 2017 at 19:05
  • It's almost impossible to give a general advice in this way. Such concerns you're having only make sense relative to concrete use cases. Commented Jun 14, 2017 at 19:06
  • 1
    "Or, I can remove the const on the returned pointer." you cannot modify an object through a const pointer, so removing const is necessitated. "Or, I can make class A be a friend of class B, then it can modify the private members of B to avoid duplication of code." yeah, if you only want to be able to modify members from A then 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, B s members shouldn't be private at all, but public. Commented Jun 14, 2017 at 19:12

1 Answer 1

1

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;
};
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.