Declared variables are not accessible in other class - c++

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.

Related

What happens when Classes that are friends have same name member variables

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.

Initializing Member Instances in C ++

I feel really stupid but I have some trouble finding the right search terms for this (probably easy) question. I think that with some code my issue is easy to understand.
I have a class that has, as a member, an instance of another class. So I go:
class Engine {
sf::Window window_;
}
Then in my .cpp file:
Engine::Engine() {
window_ = sf::Window(200,100);
}
I actually didn't know this was the wrong way to do things until I got "Object of type sf::Window cannot be assigned because its copy operator is implicitly deleted" for this particular class. I understand that I'm supposed to do sf::Window window(200,100), but how do I combine that with creating a member variable in my class (window_)?
You need to use the constructor initialization list to initialize data members:
Engine::Engine() : window_(200,100)
{
}
What you are attempting to do is to assign to a default constructed instance. This is because, once you are in the constructor's body, all data members (and base classes) have already been initialized.
You can either do it via member initialization list
Window() : window_(sf::VideoMode(640, 480), "title") {}
or by calling window_.create(arguments)

Using default constructors in C++

Hi all I am in Intro to Programming and am a little unsure about member initialization and default constructors. We are learning the basics of classes and structures but we haven't even gotten to constructor methods or inheritance yet, so I'm a little ahead of the class. I surfed the web and I couldn't find an exact answer to my question so I figured I would ask here:
class ProductionWorker : public Employee
{
private:
int shiftNum;
double hourlyPay;
public:
//constructor for ProductionWorker
ProductionWorker(int newShiftNum, double newHourlyPay) : Employee(getEmpName(), getEmpNum())
{
shiftNum=newShiftNum;
hourlyPay=newHourlyPay;
}
In this snippet the first problem that I ran into was I was getting an error that there was no default constructor for the class Employee and after some research I found out that if a class is inheriting another class, the inherited class needs to have a default constructor. I read a little more into member initialization and from my understanding, I can do away with the need for a default constructor of an inherited class if I just have the ProductionWorker constructor initialize the Employee constructor.
Is this correct?
The arguments that are passed into the Employee constructor are "getters" because I can't directly pass in the variables held in the Employee class because they are private, would this cause unforeseen problems?
Before you create a class, you cannot access its members. So Employee( getEmpName(), getEmpNum() ) makes no sense. You are supposed to pass those values into the constructor, and then later if you need them, call the accessors.
public ProductionWorker( string name, int num, int shiftNum, double pay ) :
Employee( name, num )
{
this->shiftNum = shiftNum;
this->hourlyPay = pay;
}
Inheritance is a is a relationship. When you create a ProductionWorker you are also creating a Employee. Since Employee only has a constructor that takes a name and number (I assume), those are usually passed into ProductionWorker so it can create the Employee correctly. As Noted below, there are alternatives, but this seems like the logical way in this scenario.
Base class do not need to have a default constructor. If they do not have a default constructor, each constructor of a derived class needs to explicit call one of the base class constructors from its member initializer list. However, you shouldn't attempt to use any member functions because the object isn't constructed, yet. You basically want to use the constructor arguments of the derived class to determine which values you want to pass to the base class.
In your specific example it looks as if the Employee base class wants to get a name and an employee number. You might want to pass them to your derived class in addition to the information need only by the derived object.
You understend it correctly I think but you've missused a notion.
Arguments of Employee class constructor can be it's setters, because they might allow you to set the private properties of base class.
A getter would allow you to get (no surprise) the value of private field.
By the way, constructor of inheriting class will always call the base class' constructors. Of course if the base class have constructor that accepts no arguments then there is no need to call it explicitly in inheriting class.
Imagine that you have classes:
class ColorCircle : public Circle{
string color;
ColorCircle (string c)
{
this.color = c;
}
}
and
class Circle {
double diameter;
Circle (double d)
{
this diameter = d;
}
}
If you want to create a ColorCircle you have to provide also the information about it's diameter but the constructor of ColorCircle does not have any place for this. Thats why constructor of ColorCircle should look like this:
ColorCircle (string c, double d) : Circle (d)
{
this.color = c;
}
And when you create a ColorCircle you just do:
new ColorCircle("red", 2.5);
The program takes care about passing the diameter value 2.5 to the proper base class constructor.

In what ways can a class access members of another class?

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 .

Why cant we create Object if constructor is in private section?

I want to know why cant we create object if the constructor is in private section. I know that if i make a method static i can call that method using
<classname> :: <methodname(...)>;
But why can't we create object is what I don't understand.
I also know if my method is not static then also I can call function by the following:
class A
{
A();
public:
void fun1();
void fun2();
void fun3();
};
int main()
{
A *obj =(A*)malloc(sizeof(A));
//Here we can't use new A() because constructor is in private
//but we can use malloc with it, but it will not call the constructor
//and hence it is harmful because object may not be in usable state.
obj->fun1();
obj->fun2();
obj->fun3();
}
So, my question is: why can't we create an object when constructor is private?
Because it is not accessible to the program, that's what private means. If you declared a member function or variable private, you would not be able to access them either. Creating private constructors is actually a useful technique in C++, as it allows you to say that only specific classes can create instances of the type. For example:
class A {
A() {} // private ctor
friend class B;
};
class B {
public:
A * MakeA() {
return new A;
}
};
Only B can create A objects - this is useful when implementing the factory pattern.
A constructor is a special member function. It obeys the same rules as any other method when it comes to accessing it. The private access label prevents class users from invoking/accessing members declared under it.
The "new" operator needs to call the constructor, so if the constructor is private you can not execute the code "obj = new A" except inside member functions of the class A itself.
I would guess that what you have encountered is a technique that is very often used in Java (and yes I know you're writing C++, but the principle is the same) where the designer of the class wants to make sure that one and only one instance of this class will ever exist (which is called a "singleton"). To achieve this, he needs to prevent other code from creating further instances of the class using new, and making the constructor private is one way to do that. Here's a piece of Java code illustrating the technique.
public class MySingleton {
private MySingleton() {
// Private constructor, to prevent instantiation using "new"
// outside of this class.
}
public synchronized static MySingleton getInstance() {
static MySingleton instance = null;
if (instance == null) {
// I can use new here because I'm inside the class.
instance = new MySingleton();
}
return instance;
}
}
Even if you don't know Java, the syntax is similar enough to C++ that you should understand what this code is doing. The point is that the only way to get a reference to an instance of the MySingleton class elsewhere in the code is to call the static class member getInstance().
MySingleton obj = MySingleton.getInstance();
You can't instantiate your class because the constructor is private. private member variables and functions cannot be used outside of the class itself.
If you want to be able to instantiate your class, you have two options.
Option 1 is to make the constructor. This is the Right Thing to do in the vast majority of cases. Making a constructor private is a useful technique, but only when trying to accomplish specific goals.
Option 2 is to create a public static factory method. You would typically do this when Option 1 isn't an option.
class A
{
A();
public:
static A* Create() { return new A; }
void fun1();
void fun2();
void fun3();
};
int main()
{
A *obj = A::Create();
//Here we can't use new A() because constructor is in private
//but we can use malloc with it, but it will not call the constructor
//and hence it is harmful because object may not be in usable state.
obj->fun1();
obj->fun2();
obj->fun3();
}