Passing an entire object to access its private members

I want to organize a private vector member by passing the entire object to a public function that is not inside any class.


I have a class Parent, class Child, and class Anon.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Parent{
   virtual void print()=0;
};

class Child: public Parent{
   private:
      vector<Anon*> contain;   // The vector that I want to sort
   public:
      void print(){
         //print contain
      }

      void organize(){
         sort(this); //I want to give this entire object to another function that is not inside any class to sort it
      }
};

class Anon{
   private:
      int x;
   public:
      //accessors and mutators here...
};

void sort( Parent* c ){  //I will be creating multiple children to pass here
   
   for( vector<Anon*> it = c->contain.begin(); it!=c->contain.end(); it++)  //This is where I get most of my errors
//It says "class Parent has no member named contain". How do I let the program know which children to look into?

      //begin to sort elements
}


Is there a way for me to pass a variety of children into sort() and be able to sort it!

Any tips/guidance/advice is much appreciated.
Last edited on
This is the definition of Parent:
1
2
3
class Parent{
   virtual void print()=0;
};

Parent does not have a member called "contain". It only has print(), as a pure virtual function.

I don't know exactly what your design constraints are, but if your Child class has a particular way of sorting, then make a function that accepts a Child object. And if you want this function to be able to directly access your contain vector, then you need to provide a getter, make it public, or make sort a friend. Again, it really depends on what your design requirements are, or what kinda of flexibility you want to provide.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <vector>

using std::vector;

class Parent {
   virtual void print()=0;
};

class Child;
void sort(Child& child);

class Anon;
class Child : public Parent {
   private:
      vector<Anon*> contain;
   public:
      void print(){
         //print contain
      }

      void organize(){
         sort(*this); 
      }
      
   friend void sort(Child& child);
};

class Anon {

};

void sort(Child& child) {
    for (Anon* element : child.contain)
    {
        // ...
    }
}

int main()
{
    Child child;
    child.organize();
}


If you need the sort function to take in a Parent pointer, then you should put the common data in the base class. e.g. put the vector in the base class, or make a "getContainer" virtual function.

If you told us what the actual purpose of this is, maybe someone could help come up with a design that doesn't seem contrived.
Last edited on
What’s bad in simply having your class which contains your std::vector sort it?

Example (mere draft):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <algorithm>
#include <iostream>
#include <numeric>
#include <random>
#include <vector>


class Parent {
public:
private:
    virtual void print() const = 0;
};


class Anon {
public:
    explicit Anon(int x_arg = 0);
    int getX() const;
    Anon& operator++();

private:
    int x;

//friend:
    friend bool operator< (const Anon& lhs, const Anon& rhs);
};


Anon::Anon(int x_arg)
    : x { x_arg }
{
}


Anon& Anon::operator++()
{
    ++x;
    return *this;
}


int Anon::getX() const
{
    return x;
}


bool operator< (const Anon& lhs, const Anon& rhs)
{
    return lhs.x < rhs.x;
}



class Child: public Parent {
public:
    void addElement(Anon* const value);
    void print() const override;

    void organize();

private:
    // Do not rely on raw pointers - take advantage of smart pointers or
    // std::reference_wrappers instead.
    // Also: can't you work out a better name than 'contain'?
    std::vector<Anon*> contain;
};


void Child::addElement(Anon* const value)
{
    contain.push_back(value);
}


void Child::print() const
{
    for(const auto* e : contain) {
        std::cout << e->getX() << ' ';
    }
}


void Child::organize()
{
    std::sort( contain.begin(),
               contain.end(),
               [](const Anon* const lhs, const Anon* const rhs) {
                   return lhs->getX() < rhs->getX();
               } );
}


void print(const std::vector<Anon>& what);


int main()
{
    std::vector<Anon> v(13);
    std::iota(v.begin(), v.end(), Anon(-6));
    std::shuffle(v.begin(), v.end(), std::mt19937 { std::random_device{}() } );
    std::cout << "v:\n";
    print(v);

    Child* one = new Child;
    for(auto& e : v) {
        one->addElement(&e);
    }

    one->organize();

    std::cout << "\none:\n";
    one->print();
    std::cout << '\n';
}


void print(const std::vector<Anon>& what)
{
    for(const auto& e : what) {
        std::cout << e.getX() << ' ';
    }
    std::cout << '\n';
}


Example output
v:
-2 -3 -1 5 4 2 -4 3 -5 -6 0 1 6

one:
-6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6

Topic archived. No new replies allowed.