• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 221
  • Last Modified:

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

0
codeBuilder
Asked:
codeBuilder
  • 10
  • 6
  • 5
  • +2
3 Solutions
 
Ken ButtersCommented:
I believe you have two choices:

1) change the protection level
2) add extra methods ~ getters and setters.
0
 
codeBuilderAuthor Commented:
Both is forbidden. I need another way
0
 
Ken ButtersCommented:
There is no other way.... That is what "Private" was designed to do.
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
phoffricCommented:
You can if you were able to change the class by returning a reference to the  private entity (but not recommended):
   http://www.experts-exchange.com/Programming/Languages/CPP/Q_27993008.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.
0
 
jkrCommented:
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

0
 
phoffricCommented:
And friend would work too if you were permitted to change the class definitions. But, you say you cannot.
0
 
codeBuilderAuthor Commented:
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]
0
 
phoffricCommented:
>> 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.
0
 
jkrCommented:
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.
0
 
phoffricCommented:
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.
0
 
sarabandeCommented:
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
0
 
sarabandeCommented:
the 'private' scope in class definition is more a self-restriction rather than a forbiddance. everyone who has access to a header file can easily change the 'private' to 'public' and would overcome the restraint by that without disadvantage (if used for read-only purposes and until to the next update).

if this is an academic exercise and there is no misunderstanding about the forbiddance from your site, then the task could be to find out whether it is possible to sidestep the restriction. and indeed you could access the members if you would make a copy of the class Node, which has same data members but defined public, and would do a reinterpret_cast on the nodes in vector nodes to be able to use your class instead of the original one.

of course such doing is weird if you were able to get a read-only access to the original class as recommended by experts.

Sara
0
 
codeBuilderAuthor Commented:
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

0
 
jkrCommented:
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

0
 
sarabandeCommented:
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
0
 
codeBuilderAuthor Commented:
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

0
 
jkrCommented:
The problems are the declaration of th e'friend' operators, it's 'const Network&' and then only 'Network&' in the implementation, plus 'Node' has the wrong friend - check this out:

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

class Network;

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

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

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

ostream& operator<<(ostream& stream, const 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]->label ;
				}
		}

           return stream;
	}
                                            

Open in new window


Compiles fine...
0
 
codeBuilderAuthor Commented:
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.
0
 
jkrCommented:
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

0
 
codeBuilderAuthor Commented:
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
0
 
jkrCommented:
Can you post the complete actual code you have now?
0
 
codeBuilderAuthor Commented:
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

0
 
codeBuilderAuthor Commented:
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.
0
 
sarabandeCommented:
your last code works cause Network would stream nodes[a] what is a single Node (and not nodes[a].label what is a private member of Node). Also in the stream operation of Node you moved the streaming of the label outside of the for loop for the adjacencies which apparently were empty.

you were "printing" it to the output stream which would show it on the "console" if you have a console program. at a non-console program (for example a windows program) the output would not be shown as long as you don't add code that would redirect the stream to another (output) device. a console program also could redirect standard output - for example to a file or to another program. for that case the output would not show on the console.

in your code the operator<< implementation for Network was writing to std::cout what is a mistake. instead it should write to the stream that was passed as first argument as you did it rightly in the implementation for the Node.

stream<< *(network.nodes[a]);

Open in new window

in both implementations you need to return the stream object at end (actually it should not compile without).

if using std::cout in your program, it makes some efforts to redirect that to a file. you could solve that by

int main(...)
{
       std::ostream & out = std::cout;
       ...

Open in new window


then, use 'out' instead of 'cout' for the rest. if you want to write to file, you would replace that code by

int main(...)
{
    std::ofstream out("xxx.txt") ;
    ....
    out.close();
     return 0;
}

Open in new window

what would do what you want.

Sara
0
 
codeBuilderAuthor Commented:
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?
0
 
phoffricCommented:
Looks simple enough to give it a try. If you get a compiler error, it will tell you exactly what is wrong.
0
 
codeBuilderAuthor Commented:
Thanks for your advices. I learned it with your helps
0

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

  • 10
  • 6
  • 5
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now