Solved

accessing private members related question

Posted on 2013-05-14
27
211 Views
Last Modified: 2013-05-18
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
Comment
Question by:codeBuilder
  • 10
  • 6
  • 5
  • +2
27 Comments
 
LVL 19

Expert Comment

by:Ken Butters
ID: 39166600
I believe you have two choices:

1) change the protection level
2) add extra methods ~ getters and setters.
0
 

Author Comment

by:codeBuilder
ID: 39166606
Both is forbidden. I need another way
0
 
LVL 19

Expert Comment

by:Ken Butters
ID: 39166611
There is no other way.... That is what "Private" was designed to do.
0
 
LVL 32

Expert Comment

by:phoffric
ID: 39166616
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
 
LVL 86

Expert Comment

by:jkr
ID: 39166647
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
 
LVL 32

Expert Comment

by:phoffric
ID: 39166651
And friend would work too if you were permitted to change the class definitions. But, you say you cannot.
0
 

Author Comment

by:codeBuilder
ID: 39166675
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
 
LVL 32

Expert Comment

by:phoffric
ID: 39166695
>> 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
 
LVL 86

Expert Comment

by:jkr
ID: 39166697
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
 
LVL 32

Expert Comment

by:phoffric
ID: 39166773
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
 
LVL 32

Expert Comment

by:sarabande
ID: 39167496
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
 
LVL 32

Assisted Solution

by:sarabande
sarabande earned 250 total points
ID: 39168205
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
 

Author Comment

by:codeBuilder
ID: 39168658
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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 86

Expert Comment

by:jkr
ID: 39168724
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
 
LVL 32

Expert Comment

by:sarabande
ID: 39168766
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
 

Author Comment

by:codeBuilder
ID: 39168908
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
 
LVL 86

Accepted Solution

by:
jkr earned 250 total points
ID: 39168936
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
 

Author Comment

by:codeBuilder
ID: 39169040
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
 
LVL 86

Expert Comment

by:jkr
ID: 39169075
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
 

Author Comment

by:codeBuilder
ID: 39169182
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
 
LVL 86

Expert Comment

by:jkr
ID: 39169233
Can you post the complete actual code you have now?
0
 

Author Comment

by:codeBuilder
ID: 39169325
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
 

Author Comment

by:codeBuilder
ID: 39169958
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
 
LVL 32

Assisted Solution

by:sarabande
sarabande earned 250 total points
ID: 39170677
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
 

Author Comment

by:codeBuilder
ID: 39174494
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
 
LVL 32

Expert Comment

by:phoffric
ID: 39176550
Looks simple enough to give it a try. If you get a compiler error, it will tell you exactly what is wrong.
0
 

Author Closing Comment

by:codeBuilder
ID: 39177114
Thanks for your advices. I learned it with your helps
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now