Link to home
Create AccountLog in
Avatar of codeBuilder
codeBuilder

asked on

accessing private members related question

I have a Network class which includes vectors of Nodes which includes vectors of int.
I want to print out all of int . Here is what i did . HOwever i cannot access , i take such an error:
std:vector<int> adjacencyList is private;
HOw can i access there ? I have no permission to change class declarations(adding extra method into the classes is forbidden).How can i do it?

#include <iostream>

class Node{
	public:
		Node(string label);
		~Node();
	private:
		string label;
		vector<int> adjacencyList;
};

class Network
{
	public:
		Network();
		~Network();

		friend ostream& operator<<(ostream& stream,Network& network);
	private:
		vector<Node *> nodes;
};

ostream& operator<<(ostream& stream, Network& network)
	{
		int i;
		int js;
		int s = network.nodes.size();
		for (i=0;i<s;i++)
		{
			js = network.nodes[i]->adjacencyList.size() ;
			
			for (int j=0;j<js;j++)
				{
					cout << network.nodes[i]->adjacencyList[j] ;
				}
		}
	}

Open in new window

Avatar of Ken Butters
Ken Butters
Flag of United States of America image

I believe you have two choices:

1) change the protection level
2) add extra methods ~ getters and setters.
Avatar of codeBuilder
codeBuilder

ASKER

Both is forbidden. I need another way
There is no other way.... That is what "Private" was designed to do.
You can if you were able to change the class by returning a reference to the  private entity (but not recommended):
   https://www.experts-exchange.com/questions/27993008/C-Accidental-Access-to-Private-Object-Variable.html

Since you cannot modify the class, there is no way to access private members unless the class programmer made a "mistake" in his implementation by returning a reference.

The point about the member being private in C++ is that the class implementer/designer can change the private members to anything they want without affecting the developers who use their code. If they want to change a vector to some other container, that will be transparent to the users of their class.
Actually, this is the case for which 'friend' was created.Just use it in 'Node' like in 'Network', e.g.

#include <iostream>

class Network; // fwd. decl.

class Node{
	public:
		Node(string label);
		~Node();
		friend ostream& operator<<(ostream& stream,Network& network);
	private:
		string label;
		vector<int> adjacencyList;
};

class Network
{
	public:
		Network();
		~Network();

		friend ostream& operator<<(ostream& stream,Network& network);
	private:
		vector<Node *> nodes;
};

ostream& operator<<(ostream& stream, Network& network)
	{
		int i;
		int js;
		int s = network.nodes.size();
		for (i=0;i<s;i++)
		{
			js = network.nodes[i]->adjacencyList.size() ;
			
			for (int j=0;j<js;j++)
				{
					cout << network.nodes[i]->adjacencyList[j] ;
				}
		}
	}
                                  

Open in new window

And friend would work too if you were permitted to change the class definitions. But, you say you cannot.
friend is not permitted too. Why can't i access the member of Node with node object ?Is the reason : calling it inside Network object? That is why i can't access it , right?
network.nodes[0]->adjacencyList[0]
>> network.nodes
Stop, right there. network is an instance of Network class.
nodes is a private member of Network class.
So, if network were defined, say, in main(), then this network object from main() cannot access the nodes member because it is private in the Network class.
You are already using 'friend' in your code, so why should that be forbidden? *puzzled*

Anyway, if you absolutely cannot change the class definitions, the private members of 'Node' are completely inaccessible.
You may not have permission to do this on your own, but you can ask the Node author to add what you need. (You want to leave private: alone - you should be denied a request to change that as now you would be permitted to wreak the vector.) You may want to ask for a read-only iteration capability to be added to the Node class so that you can read the integer values in your adjacencyList.
to add to above comments:

the current definition of Node is not complete and makes no sense. class Node only has public constructor and destructor but no member function where you could access the private members. the smallest change to the class Node is to make class Network a friend (that is a commonly used construct that 'nodes' can be used by their 'friend' list class - only).

if that is not allowed, the class Network could add new Node objects but could not access them what apparently is a wrong or incomplete design.

Sara
SOLUTION
Avatar of sarabande
sarabande
Flag of Luxembourg image

Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
At first i didn't mind one line thus i didn't write it here. HOwever , it may be possible to do what i want maybe.It is close to jkr's sayings.THere is one friend ... in Node class ,too.
Here is the new code:
#include <iostream>

class Node{
	public:
		Node(string label);
		~Node();
                friend ostream& operator << (ostream& stream, const Node& node);  // ADDED!!
	private:
		string label;
		vector<int> adjacencyList;
};

class Network
{
	public:
		Network();
		~Network();

		friend ostream& operator<<(ostream& stream,Network& network);
	private:
		vector<Node *> nodes;
};

ostream& operator<<(ostream& stream, Network& network)
	{
		int i;
		int s = network.nodes.size();
		for (i=0;i<s;i++)
		{
			
			for (int j=0; j<1? ;j++)
				{
					out << network.nodes[i] ;  //here , it prints only address however i need to call below operator overloading function , i think 
				}
		}
	}

ostream& operator<< (ostream& stream, const Node& node)
{
		int i;
		int s = node.adjacencyList.size();
		//Node * nd;

		for (i=0;i<s;i++)
		{
			stream << "yihuu";
		}

}

Open in new window

That one is basically missing a header file and some variable names are incorrect is 'operator<<()' - the following compiles fine:

#include <iostream>
#include <vector>
using namespace std;

class Node{
	public:
		Node(string label);
		~Node();
                friend ostream& operator << (ostream& stream, const Node& node);  // ADDED!!
	private:
		string label;
		vector<int> adjacencyList;
};

class Network
{
	public:
		Network();
		~Network();

		friend ostream& operator<<(ostream& stream,Network& network);
	private:
		vector<Node *> nodes;
};

ostream& operator<<(ostream& stream, Network& network)
	{
		int i;
		int s = network.nodes.size();
		for (i=0;i<s;i++)
		{
			
			for (int j=0;j<s;j++)
				{
					stream << network.nodes[i] ;
				}
		}

           return stream;
	}
                                            

Open in new window

if you change
stream << "yihuu";

Open in new window

by
stream << adjacencyList[j] << ' ';

Open in new window

you should get a valid output in case the adjacencyList was filled (somehow ???) for your nodes.

Sara
I think the below code MUST work . BUt it doesn't work :S
IN the first op. overloading i try to call another op. overloading by writing:
cout << network.nodes[a];   // It must call second op. overloading but it doesn't work.

ostream& operator<<(ostream& stream, Network& network)
	{
		int a;
		int s = network.nodes.size();
		for (a=0;a<s;a++)
		{
					cout << network.nodes[a];	
		}
	}

ostream& operator<< (ostream& stream, const Node& node)
{
		int a;
		int s = node.adjacencyList.size();
		for (a=0;a<s;a++)
		{
			stream << node.label ;
		}
}

Open in new window

ASKER CERTIFIED SOLUTION
Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
it's forbidden to change class declarations. It must be:
friend ostream& operator << (ostream& stream, const Node& node);   in Node class
and
friend ostream& operator<<(ostream& stream,Network& network);

We have to do something in op. overloading function bodies.

Besides, i tried to change friend declarations as you said above, but it still says that label is private.
Well, OK - then focus on the decarations and make sure that they read

friend ostream& operator << (ostream& stream, const Node& node);

Open in new window


and

friend ostream& operator<<(ostream& stream,const Network& network);

Open in new window


and that the implemetations match, i.e.

ostream& operator<<(ostream& stream, const Network& network)
{
  // ...

  return stream;
}

ostream& operator<<(ostream& stream, const Node& node)
{
  // ...

  return stream;
}

Open in new window

OK.Then my question is :
when i write
cout << *node

it call the overloading operator :
ostream& operator<< (ostream& stream, const Node& node)
{
		int a;
		int s = node.adjacencyList.size();
		for (a=0;a<s;a++)
		{
			stream << node.label ;
		}
}

Open in new window




HOwever , when i write
cout << network.nodes[0];
or
cout << *(network.nodes[0]);

neither calls  the overloading operator :
ostream& operator<< (ostream& stream, const Node& node)
{
...
}

Open in new window


My main target is to call ostream& operator<< (ostream& stream, const Node& node) , from the body of  ostream& operator<<(ostream& stream, Network& network) . I cannot do it in anyway. If i can do it , there will be no problem
Can you post the complete actual code you have now?
OK.It worked when i did it as below.Thanks for help and suggestions :)
ostream& operator<<(ostream& stream, Network& network)
	{
		int a;
		int s = network.nodes.size();
		for (a=0;a<s;a++)
		{
					cout << *(network.nodes[a]);	
		}
	}

ostream& operator<< (ostream& stream, const Node& node)
{
		stream << node.label ;
}

Open in new window

At the above code , am i printing it to output stream ? Or am i printing it to directly to terminal ? Second option is forbidden and the code must be appropriate to print it to a file.


I tried to do the below things in the code:
When << operator is called with Network object ,
cout << -node object - is called
Then i print the contents of node object to stream.
SOLUTION
Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
Class A
{
vector <B> x;
}

Class B
{

private:
int number;
}

Elements of x is type of B.  Can vector elements of x access the number?
Looks simple enough to give it a try. If you get a compiler error, it will tell you exactly what is wrong.
Thanks for your advices. I learned it with your helps