C++ object of class in class not given public access - c++

I have this setup and how i want to use it in main for example:
struct Player{
private:
float posX1, posX2, posY1, posY2;
int user_id;
public:
Player::Player():posX1(NULL), posY1(NULL), posX2(NULL), posY2(NULL){};
float getPosX1();
float getPosY1();
float getPosX2();
float getPosY2();
int getUserId();
void setUserId(int);
void setPosX1(float);
void setPosY1(float);
void setPosX2(float);
void setPosY2(float);
};
struct Room_Data{
private:
int room_id;
Player player_one, player_two;
bool playerOneAlive, playerTwoAlive;
public:
Room_Data::Room_Data():player_one(), player_two(), playerOneAlive(false), playerTwoAlive(false), room_id(NULL){};
void setRoomId(int);
int getRoomId();
void setPlayerOneDead();
void setPlayerOneAlive();
void setPlayerTwoDead();
void setPlayerTwoAlive();
bool isPlayerOneAlive();
bool isPlayerTwoAlive();
Player getPlayerOne();
Player getPlayerTwo();
};
I'm trying to use the following method in main for example:
main.cpp
const int x=10;
Room_Data data[x];
data[0].getPlayerOne().setPosX1(10.0f);
But it doesnt set posx1 because getPlayerOne() provides only private access of the player_one object but i dont know how to give it public access

By having getPlayerOne return a reference to that private variable.
Player& getPlayerOne();
Then you will be able to perform stuff on the result of calling that function, and that stuff will apply to the actual, original member within your class.
Right now you're operating on a temporary copy, instead, due to returning by value.
Frankly, though, if you're going to allow unabashed access to this private variable, why bother with the getter? Just make the variable public.

Related

How to swap 2 different objects of an object array in C++?

I'm trying to write a Swap function to swap 2 different types of objects of an array in C++. How can I do that? (I prefer using pointer to solve this problem)
I've tried to use template classes to swap 2 objects because the types of object are different from others and when looping through the array, I don't know which objects that one element belongs to.
I have 3 classes (Object_A, Object_B and Object_C) as below:
class Object_A : public base_class
{
private:
int workingTime;
int relaxTime;
float salary;
public:
Object_A();
virtual ~Object_A();
float Cal_Salary();
int getWorkingTime() const;
void setWorkingTime(int workingTime);
int getRelaxTime() const;
void setRelaxTime(int relaxTime);
float getSalary() const;
void setSalary(float salary);
};
class Object_B : public base_class
{
private:
float income;
public:
Officer();
virtual ~Officer();
float getIncome() const;
void setIncome(float income);
};
class Object_C : public base_class
{
private:
std::string role;
float roleCoef;
float bonus;
public:
Manager();
virtual ~Manager();
float Cal_Bonus();
const std::string& getRole() const;
void setRole(const std::string& role);
float getRoleCoef() const;
void setRoleCoef(float roleCoef);
float getBonus() const;
void setBonus(float bonus);
};
// I tried to write SwapValues func
template<class T, class U>
void SwapValues(T* a, U* b)
{
T temp = a;
a = b;
b = temp;
}
I have an array with base_class type to store some elements of three objects above (Object_A, Object_B and Object_C).
However when I want to swap one element of Object_A to one of Object_C with SwapValues() func, it doesn't work!
Thanks a lot for your help.
EDIT: Re-reading your question, the reason why your pointerswap doesn't work is because you are not passing the pointers as reference. If you insist on calling the function SwapValues, you can implement it like this:
class base_class {
// ...
friend void SwapValues(base_class*& a, base_class*& b) {
::std::swap(a,b);
}
};
Observe that SwapValues is still free function, not a member function.
You should always use ::std::swap as it sometimes offers efficient alternatives:
::std::swap(*a,*b);
You can also implement a member function in your class if you want to customise how swap works. For instance, your members can be swapped efficiently, as they are either POD or ::std::string which has a constant-time swap.
I think you should try
void SwapValues(T* a, U* b)
{
T* temp = a;
a = b;
b = temp;
}
Since your array consists of pointers (base_class* elements), you don't need your own swap function. You can just assign such pointers normally, and thus you can just use std::swap.

How to unit test if a private variable has changed

Let's say that I have this class in C++:
class ExampleClass{
private:
int example_var;
public:
void exampleMethod(){
example_var = other_value; // other value will be always different
}
}
How can I unit test exampleMethod()? I would like to do something like this:
void testExampleMethod(){
ExampleClass obj;
int before_call_value = obj.example_var;
obj.exampleMethod();
int after_call_value = obj.example_var;
ASSERT_NOT_EQUALS(before_call_value, after_call_value);
}
But example_var is private.
So, what is the right way to do this unit test? How can I test if a private example_var has changed?
Short answer: Dont do it.
Your test should test against the public interface only. Let me try to explain with some code:
class Adder {
int a,b;
public:
Adder() : a(0),b(0) {}
void set(int x,int y) { a=x;b=y; }
int get() { return a+b; }
};
and a test (assume for a moment we had access to a and b):
void testAdder(){
Adder add;
int a = 1;
int b = 2;
add.set(a,b);
ASSERT_EQUALS(add.a,a);
ASSERT_EQUALS(add.b,b);
ASSERT_EQUALS(add.get(),a+b);
}
Suppose you already distributed the code and someone is using it. He would like to continue using it but complains about too much memory consumption. It is straightforward to fix this issue while keeping the same public interface:
class Adder {
int c;
public:
Adder() : c(0) {}
void set(int x,int y) { c = x+y; }
int get() { return c; }
};
That was easy, but the test will fail :(
Conclusion: Testing private implementation details defeats the purpose of testing, because each time you modify the code it is likely that you also have to "fix" the test.
It is bad approach to test private variable/methods. But if you need there are a lot of options:
You can make Your test class as friend of ExampleClass
You can grab information using moc object
If you want to access example_val, there are one of two things you can do. The first is by making testExampleMethod() a friend method, as follows:
class ExampleClass{
private:
int example_var;
public:
void exampleMethod(){
example_var = other_value; // other value will be always different
}
friend void testExampleMethod(); //Now you can use the function as is.
}
On the other hand, you could just add a getter to your ExampleClass to access the variable, such as the following:
class ExampleClass{
private:
int example_var;
public:
void exampleMethod(){
example_var = other_value; // other value will be always different
}
inline void getExampleVar() const { return example_var; }
}
And then change testExampleMethod() to:
void testExampleMethod(){
ExampleClass obj;
int before_call_value = obj.getExampleVar();
obj.exampleMethod();
int after_call_value = obj.getExampleVar();
ASSERT_NOT_EQUALS(before_call_value, after_call_value);
}
I would honestly use the second method, since accessing a class's private variables is generally not recommended.
You just simply implement get function for that private variable you want to get.
class ExampleClass{
private:
int example_var;
public:
void exampleMethod(){
example_var = other_value; // other value will be always different
}
int GetExampleVar(){
return example_var;
}
}
And call it like
void testExampleMethod(){
ExampleClass obj;
int before_call_value = obj.GetExampleVar();
obj.exampleMethod();
int after_call_value = obj.GetExampleVar();
ASSERT_NOT_EQUALS(before_call_value, after_call_value);
}
Or make testExampleMethod friend function (friend function can access private variables of friend class even if its not its method).
class ExampleClass{
private:
int example_var;
public:
void exampleMethod(){
example_var = other_value; // other value will be always different
}
friend void testExampleMethod();
}
In my opinion first example would be more suitable, but if you cannot modify ExampleClass, you can turn off access control for gcc -- -fno-access-control.
A few options I can think of:
1) Make the test code a friend of the class. That way it can access the private members.
2) Add a getter to the class that's under a #ifdef Testing directive that only gets defined when building the test version (or put public: under that macro and a private: in the #else branch).
3) #define private public when building the test (no, not really).
4) Use gcc's -fno-access-control flag when building the version to test, so that everything is public (if you are using gcc that is).
5) Just give up testing externally from the class and instead add relevant static_asserts/asserts to the class itself to test invariants.
6) Don't. Just stick to testing the public interface.
Hope that helps :-)

Dont allow access to member variable directly within same class

I am not sure is my question is right or not? But let me still try to ask once.
I have a Class with have few member variables defined. As per OO concepts, every member function can access , all member variables of its class.
But I want these member variable to be accessed via specific methods (Lets say Getters) , even within same class member functions.
It there any way to do it?
class A {
public:
void func1();
void func2();
B getB();
private:
B b;
}
void A::func1() {
b.functionFromB(); // function uses member variable b directly
}
void A::func2() {
B b1=getB(); // function ask for B from a function and then uses it. // I need something like this... And ensure each function uses same way otherwise there should be warning...
b1.functionFromB();
}
Thanks,
Kailas
No, there is not. You can do it via encapsulation and inheritance like:
class shape
{
private:
int angles;
protected:
shape(int angles_):angles(angles_){};
int getAngles() const;
}
class square : private shape
{
public:
square():shape(4){}
void doSth()
{
\\ you can access angles only via getAngles();
}
}
Any private members of the class can be accessed from within the class, but not by users of the class. So it looks like you need private members and public methods that allow access to them.
class A
{
private:
int a;
public:
int getA() {return a;}
};
int main()
{
A inst;
int t;
inst.a =5; // error member a is private
t = inst.getA(); //OK
}
The concept extends fine to nested class declarations in case you only want to allow instance of a class to be created from another class; details here
As others have said - you have to add an additional layer.
If you want to give access to specific methods then you can use the friend keyword. E.g.
// Public.h
#pragma once
class Public
{
public:
Public();
int GetI() const;
float GetF() const;
private:
std::unique_ptr<Private> p_;
};
//Public.cpp
#include "Public.h"
Public::Public()
: p_(new Private)
{
}
int Public::GetI() const
{
return p_->i_;
}
float Public::GetF() const
{
return p_->f_;
}
// Private.h
#pragma once
class Private
{
friend int Public::GetI() const;
friend float Public::GetF() const;
int i_;
float f_;
};
Keep in mind that every friend method can access ALL private members.
If you really really want to limit which methods can access which members then you can wrap each member in a separate class/struct and make only the getter/setter of that member a friend of that class/struct but I would not recommend this approach.

Pointers disappear after calling sub-routine of child class

I am trying to do One class with some features that will be em common with other (Inheritance). This is my principal class:
class SREngineJulius_father {
protected:
bool g2pInit;
Recog *recog;
Jconf *jconf;
public:
bool InitG2P(std::string dic, std::string model, int pos_process_flag=-1);
bool Init_AM(std::string configStr);
};
The two function InitG2P and Init_AM, will make updates in recog and jconf. This updates is something that all child objects of the child class must have.
class SREngineJulius: public SREngineJulius_father
{
DFA_INFO *dfaInfo;
WORD_INFO *wordInfo;
WORD_INFO *wordInfo_init;
Output lastResult;
TListString lastCmdList;
bool startNotifyCallbackLoop;
bool terminate;
bool pause;
DFA_INFO* copy_dfa_info(DFA_INFO* dfa);
DFA_INFO* create_commands_dfa_info();
static void status_recready(Recog *recog, void *dummy);
static void status_recstart(Recog *recog, void *dummy);
static void output_result(Recog *recog, void *dummy);
static void put_hypo_phoneme(WORD_ID *seq, int n, WORD_INFO *winfo);
std::string ReplaceSpace(std::string &str);
std::string RestoreSpace(std::string &str);
public:
bool InitG2P(std::string dic, std::string model, int pos_process_flag=-1);
char* NotifyCallbackLoop(char *ficheiro_wav);//AXY5
int SREngineJulius::Audio_Buffering(char* buffer_audio, int sizefile, int end_flag_, int flag_alocation);//AXY5
void Callbacks();
public:
~SREngineJulius();
bool InitSREngine(std::string recoConfig);
bool DynamicAddCommands(TListString &cmdlist, int startRecog = -1);
bool DynamicAddCommands(std::string cmdlist, std::string sep=" ", int startRecog = -1);
void Release();
};
So the problem is, when I call a routine of the child class, recog and jconf are deleted.
You should make functions in your class that edify the two variables. Try inserting those into a anonymous struct. That way they're easily accessible.
Remember:
. =reference
-> =pointer
Lastly, you are changing recog in a couple of those function declarations.
Try to make sure that the functions are friendly in the functions you make. If they are not, you won' be able to use them.
P.s. children of child classes, these need accessor functions. They have to change the pointers through upward inheritance. So you would want to have the child class of the grandparent have a class that changes it's pointers. You would do that by having a function which accesses the child, in the grandchild. That way you're receding back into the function. That's how it's related.

why getting errors in c++ program?

I think I have coded everything correctly in this program but still getting errors.
The object si it says it's not accessible.
#include<conio.h>
#include<iostream.h>
class s_interest
{
int p,t;
float r;
s_interest(int a, int b, float c)
{
p=a;
r=b;
t=c;
}
void method()
{
int result=(float)(p*t*r)/100;
cout<<"Simple interest:"<<result;
}
};
void main()
{
int pr,ti;
float ra;
cout<<"\n Enter the principle, rate of interest and time to calculate Simple Interest:";
cin>>pr>>ti>>ra;
s_interest si(pr,ti,ra);
si.method();
}
When the compiler tells you that something is not accessible, it's talking about the public: vs. protected: vs. private: access control. By default, all members of a class are private:, so you cannot access any of them from main(), including the constructor and the method.
To make the constructor public, add a public: section to your class, and put the constructor and the method there:
class s_interest
{
int p,t;
float r;
public: // <<== Add this
s_interest(int a, int b, float c)
{
...
}
void method()
{
...
}
};
Default member access for a class is private (whereas the default for struct is public). You need to make the constructor and method() public:
class s_interest
{
int p,t; // private
float r; // also private
public: // everything that follows has public access
s_interest(int a, int b, float c) { .... }
void method() { ....}
};
Note also that void main() is not standard C++. The return type needs to be int, so you need
int main()
{
...
}
And finally, iostream.h is not a standard C++ header. You need to include <iostream> if you are using a standards compliant C++ implementation.
Following High Integrity C++ Coding Standard guidelines, always declare first public, then protected and private members. See Rule 3.1.1 of hicpp-manual-version-3-3.pdf
All the variables & functions in your class are private. This is the default when access is not specified with the private: , protected: and public: specifiers. I suggest you have a good read of a tutorial - google C++ classes.
also it is int main() and never void main()
The problem is due to access specifiers. By default class methods and data members are private. Make your data members private and methods public. so you can set the private data members value using public methods.
class{
private:
int a;
int b;
int c;
public:
void method();
void print_sum();
};