In C++, what happens when I have the following
class House
{
public:
House();
~House();
private:
int* m_peopleInside;
friend class Room;
};
and then in the constructor of House this is set
m_peopleInside = new int[5];
m_peopleInside[4] = 2;
and
class Room
{
public:
Room();
~Room();
Update();
private:
int* m_peopleInside;
};
Then in the Room.Update() I use m_peopleInside something like this.
&m_peopleInside[4];
It's my understanding that the friend class will allow the Room class to access private members of the House class. So which m_peopleInside would be used?
I should add that in this case, m_peopleInside is being used as an array.
It's an instance variable. So it needs an instance to act on. If no instance is provided, then it is the same as this->m_peopleInside, which means it refers to the instance on which the function was called. So, for example, if this is your function:
void Room::Update() {
// these two are the same, they null the member of the Room object
m_peopleInside = nullptr;
this->m_peopleInside = nullptr;
House h;
// should be pretty obvious what this does
h.m_peopleInside = nullptr;
}
It's my understanding that the friend class will allow the Room class to access private members of the House class.
That is correct.
So which m_peopleInside would be used?
To access the m_peopleInside member of a House object, you will need an object or pointer of type House.
In Room::update(), if you simply use m_peopleInside, it will be member variable of Room, not House.
When you use "m_peopleInside" inside "Room.Update()" you will definitely use the data member of "Room". Your understanding of "friend" classes is not so correct. To make it clear, suppose that you have an object "x" from the class "House" in one of the methods of the class "Room', like "Update()" for example. Then, the following code is correct in this method:
cout << x.m_peopleInside;
Although "m_peopleInside" is private in "House", it is accessible from Room's methods, because the class "House" declares that "Room" is a friend of his.
Related
class crect
{
CPoint startpt;
CPoint endpt;
int lnwidth;
crect(CPoint from, CPoint to, int wd) //constructor
{
startpt = from;
endpt = to;
lnwidth = wd;
}
};
class shape
{
crect *rect = new crect(from, to, wd); // wd showing error at this line
};
Am using above constructor in shape program then its showing error at wd...
Two things
first make sure all the variables exist (from to and wd )
Second your constructor is private so you can not create a class object outside the class . Just think of it like you have a private int a; in your class and you are trying to access a using an object like obj.a;
What you are doing here is similar to singleton design pattern . Where you make the constructor private so that no one can create an object apart from getInstance() method of class .
So declaring constructor as public should solve the problem for you if my guess is correct.
The scope of from, to, wd does not extend outside of the constructor of crect.
Using the same names as the parameters does not work - you need to specify actual values or pass in other variables that are declared in scope.
Quick tutorial on Scope
Members of a class become private by default if you don't indicate the access specifier so to me it seems like both your constructors are private.
guys, I encountered this problem on a tech blog,the question asked what are the correct solution to resolve the compiler error generated in the below code. I have searched for hours and can not get an answer.
class SomeClass
{
public:
int data;
protected:
class Nest
{
public:
int nested;
};
public:
static Nest* createNest(){return new Nest;}
};
void use_someclass()
{
SomeClass::Nest* nst = SomeClass::createNest();
nst->nested = 5;
}
A. Make function void use_someclass() a friend of class SomeClass.
B. Make the function createNest() a non-static function of SomeClass.
C. Declare the class Nest in public scope of class SomeClass.
D. Make the object nst a reference object, and make the function
createNest() return a Nest&.
E. Derive a class from SomeClass. Make the object nst a derived class
pointer so that it can access SomeClass's protected declarations.
C is certainly right and trival.
I believe A is also right, and espectially E is a classic way of doing this kind of things.
I want implement what is said in E, but have a few difficulites. (I hope someone can also implement the idea in A), below is my code:
class derived:public SomeClass{};
void use_someclass()
{
derived::Nest *nst=SomeClass::createNest();
nst->nested = 5;
}
in the above, the idea is we can access the Nest definition from a derived class.
in function use_someclass(), in the first line, the right hand side is a static function, and returns type Nest*, but on the left hand side, I don't know how to match the right hand side type. "derived::Nest" is wrong. compiler error: can not access protected member. Nest is only a definition in SomeClass, not member.
what can we use to replace "derived::Nest"? derived certainly saw the definition of Nest, but I don't know how to "say" it. Maybe somehow via "this" pointer.
You can change the visibility in your derived class:
class derived : public SomeClass {
public:
using SomeClass::Nest;
}
I have a base class and a class derived from it. In the example below, Frame_Pic is a derived class of Base_Pic, the details of which I have not included. Frame_Pic has members, vertical,horizontal, and corners which is not in the base class. Picture is an interface class and basically holds a pointer to Base_Pic.
When I try to assign new values to these in the reframe function below, I get an error stating that Base_Pic has no such data members.
The action, pic.p->vertical, will think I am accessing the base class. If I put these data members in the base class, the rest of my functions are written in a way that it will not accommodate this addition. How can I assign to these data members?
Picture frame(const Picture& pic, char v, char c, char h)
{
Frame_Pic* temp = new Frame_Pic(pic.p);
temp->vertical = v;
temp->horizontal = h;
temp->corners = c;
Picture temp2(temp);
return temp2;
}
void reframe(Picture& pic, char v, char c, char h)
{
pic.p->vertical = v;
pic.p->horizontal = h;
pic.p->corners = c;
}
Sounds like you want to set items of a derived class while feeding a function a pointer to the base type. The way to do this is to create a virtual function in the base class and implement it in the derived class.
for instance...
virtual void BaseClass::SetupSomeStuff(...) {
}
void DerivedClass::SetupSomeStuff(...) {
your assignments here
}
Instead of accessing them directly, use your Picture interface to declare set and get methods (assuming both are needed) for those members, and implement them in the derived class.
Direct access to member variables does not behave polymorphically, hence your error.
You should rethink the way you wrote the functions and how the classes interact in general.
Reframe might be a function member of Frame_Pic but its functionality has nothing to do with any instance of the class Frame_Pic. In fact, since all you can know for sure is that Picture holds a pointer to a Base_pic, it might as well hold a pointer to an instance of a different class that derives Base_pic that does not define members named vertical, horizontal or corners.
You should instead create a new Frame_pic instance like you did in the first function and set the pointer in Picture to that new instance. You might also want to mark these two functions as static if they are not, already.
I got my main class Game:
Game.h:
class Game{
public:
Galaxian galaxians[6][10];
};
Game.cpp:
Nothing interesting, just filling the variables of the class array
Galaxian.h:
class Galaxian{
public:
void update();
};
Galaxian.cpp:
Here is my problem: I want to access the galaxians array from the Game class, but I have no idea how! When I try game::galaxians I get the error "A nonstatic member reference must be relative to a specific object"
What I am trying to accomplish is that I can loop trough that array and change a value of each key in it.
How can I do that?
This is because the galaxians member is an instance member, not a class (i.e. not a static) member. You should either (1) make an instance of Game available at the point where you need to access galaxians, or (2) make galaxians a static member.
If you decide on the first way, consider making Game a singleton; if you decide on the second way, do not forget to define your galaxians array in a cpp file, in addition to declaring it static in the header file.
Non-static members are bound to an instance of a class, not to the class itself. This is general OO, not specific to C++. So you either bind the access to an object, or the member to the class:
Game g; //create an object of the class
g.galaxians; //access the member through the object
or
class Game{
public:
static Galaxian galaxians[6][10]; //bind the member to the class
};
//...
Game::galaxians; //access it through the class
Which one you choose depends on your logic.
You need to access an instance of Game:
Game g;
g.galaxians[3][4] = ....;
Earlier, I asked a question on how to call a static member's member functions so as to initialize it before making actual use of the static object. Then, I realized that I was perhaps making use of the static member in a wrong way, which led to this question:
Given a particular class, MyClass, in how many ways can we design our code so that MyClass can gain access to the member functions of another class, YourClass? [N.B. Assume a generic situation where MyClass is declared in MyClass.h and defined in MyClass.cpp, and similarly for YourClass.]
I can think of a few, but being far from an expert, I guess you could name several others:
Containment: This can come in several 'flavors', with direct containment of a YourClass object being one option, while containing a pointer or reference to the object being another option:
class MyClass
{
public:
// Some MyClass members...
private:
YourClass instance; // or YourClass* instance / YourClass& instance;
// Some other MyClass members...
};
a) Of course, direct containment is convenient, but I can think of one immediate drawback: if YourClass is a bit hefty in terms of memory requirement, and you have several MyClass instances (as in my linked question), containing the object directly will be out of the question. Besides, the has-a relationship does not always make sense.
b) Having a pointer or a reference to the object might make better sense in that case. Using a reference has the problem that you might end up referring to an object which does not exist anymore, so you have to make sure that the YourClass object exists for the duration of the existence of the MyClass object.
c) In the case of a pointer, the problem above still exists, but you can more easily reassign the pointer to a new object.
Inheritance: One can inherit from the YourClass object, so that the members are inherited, such as:
class MyClass : public YourClass
{
public:
// Some MyClass members...
private:
// Some other MyClass members...
};
a) This is also very simple to set up for a few classes, but may become unwieldy for general use. For example, if YourClass was a random number generator, it wouldn't necessarily make sense to say MyClass is-a random number generator. One can of course define a wrapper class for the random number generator, say call it Randomizable and then MyClass could inherit from Randomizable, which makes good sense.
I would personally like to know more about the pros and cons of static members, global objects, singletons, and how they are correctly used. So, from a 'meta' point of view, what other methods or patterns would work?
PS. Though I'm asking from a C++ perspective, I guess the same could be said to apply for many other object oriented languages, so don't worry about giving examples in other languages.
There are basics about C++ class membership access.
You can access a member of your own direct class (public, protected or private)
class Foo {
public:
int fooMember;
};
int main() {
Foo foo;
foo.fooMember = 1;
}
You can access protect and public members of your parent class within the child class, and then depending on the inheritance indicator in the child class declaration the members of the parent are passed on to public, next-child, or kept private
class Animal {
protected:
int feet;
int age;
public:
enum color { blue, red, green, pink } color;
Animal(int feet) { this->feet = feet; }
bool getFeet() { return feet; }
void setAge(int a) { age = a; }
};
class Elephant: public Animal {
public:
Elephant(void):Animal(4) { }
int hasFeet(void) { return (feet > 0); }
};
// Here you can override stuff too so:
class Fish: protected Animal {
public:
int teeth;
enum Type { freshWater, saltWater } type;
Fish(void):Animal(0) { }
};
class Mackerel: private Fish {
public:
Mackerel(): Fish() { teeth = 12; } /* compiles */
};
class SubMackerel: public Mackerel {
public:
SubMackerel() { teeth = 8; } /* does not compile teeth not accessible here */
} ;
int main() {
Elephant pink;
Fish fishy;
Mackerel mack;
pink.color = Animal::blue;
// this won't compile since color is protected in Fish
// fishy.color = green;
fishy.type = freshWater;
// mack.type = saltWater; // will fail
}
the last way is to declare friends. A friend class can access all public and private members of the class it is a friend to.
Well this should be a start... You can read more about it
I have been looking for the answer about the kind of same thing , and landed here.
Buy anyway , atleast I should tell you what till now I have learned about this problem.
Avoid using another class as data member , if that's not the case and you have to use it, then use pointer to that another class.
Now, if you are using pointer to the another class , always deep copy , so you have to provide a copy constructor with a deep copy to avoid invalid address assignment .
Or just use smart pointers .