OBject access from different functions in VC++ - c++

I have 3 function in my class B. These three function have to access member function of other class A.
I did this by creating object of class A in class B constructor and tried to access that object in functions of class B. But its showing error.
How can i assess the same object in these three functions. Where i have to create object of class A
B::B()
{
A a;
}
B:: function()
{
a.fun(); //fun belongs to class A
}
B:: function1()
{
a.fun1(); //fun1 belongs to class A
}
I am getting error, How can i implement the same where i can access object a in both function.

You should add A as a member of your B class, and not as a local variable of the B constructor.
Try this:
class B
{
public:
B();
void function1();
private:
// This is your member, and you can access it from all of B's methods.
A m_a;
};

You need to make a a member variable of class B like this:
class B
{
private:
A a;
// ...
}
That will make it available to all the member functions of B.
(Making it private isn't necessary - the decision to make it private, protected or public depends on whether you want to make it available only within B, within B and B's derived classes, or everywhere.)

Related

Encapsulation in header files

I have a header file with 2 classes. class A (which is a very big class) and class B that inherits class A. I don't want people to be allowed to create objects of class A or even be able to see its static members. They should only to work with class B. What is the best way of doing that.
(Generally speaking A is a "helper class")
To restrict the creation of the class, make the constructor of class A private and declare class B as a friend class. This way only B can instantiate A.
class B;
class A
{
private:
A();
friend class B;
};
The same applies to methods (static or not): make them all private and the friend statement will allow B to access A's members.
Edit: works with protected as well.
I don't want people to be allowed to create objects of class A
What you are looking for is called an "abstract base class". In C++, any class that has at least one abstract member is automatically an abstract class, there is no additional keyword like in other languages.
class A
{
public:
virtual void Test() = 0; // abstract, has no implementation
};
class B : public A
{
public:
virtual void Test() {} // not abstract, has an implementation
};
int main()
{
A a; // this will produce a compiler error.
B b; // this is fine
return 0;
}
or even be able to see its static members
Well, don't make them public. Either make them protected or private and grant friend access to your B class.

When creating an instance of a nested class, is an instance of the nesting class being made too?

When creating an instance of a nested class, is an instance of the nesting class being made too?
If not then the child only have access to static public (and protected) functions of the parent?
For example:
class a {
public:
void baz();
class b {
public:
void foo();
};
};
int main(){
a::b bar; //is an instance of a being made too?
bar.foo();
}
Two points:
Adressing your question title, the answer is yes, a derived class always contains a subobject of its base class(es). I'd also prefer base class and derived class over parent class and child class, because of the "is-a" relationship. A derived class instance is a base class instance, but a child is not a parent.
Addressing your question body, you don't have parent/child or base/derived classes. The construct you have there is a class nested inside some other class. This is something completely different. Basically, this just creates a second class who's name is nested inside the other class' "namespace". Creating an instance of the nested class does not create an instance of the nesting class though.
The "parent/child" terminology is commonly used to describe inheritance relationships, which your code doesn't have. Bearing that in mind, b doesn't have any data members or base classes of type a, so the answer is no. No object of type a is created.
Note that by virtue of being an inner class, b has access to a's non-public members.
void a::b::foo() {
a obj;
obj.some_private_member(); // OK
}
Class b is a member of class a. It is a nested type declaration. Neither subobject of this nested type is declared in the class a. So you may not call non-static member function foo because an instance of class b is required.
On the other hand, the definition of the nested class b does not include a subobject of class a. Any class has only those members that are declared inside the class definition.
So in this statement
a::b bar; //is an instance of a being made too?
there is created an instance of class b that according to its definition has only one member - member function foo
The new parameters given in class b will be the same ones as "a" along with any additional parameters.
class a {
public:
void bar();
}
class b : public a
{
public:
void foo();
}

How can I modify the protected values of a variable of a base class in a derived class function?

class abc{
protected:
int x;
};
class b: public abc{
public :
void something(abc a){ a.x = 1;}
};
I get an error in the second last line stating that I cannot access member x of variable a.
Error: Protected Member "abc::x" is not accessible through a "abc" point or object.
Is there another way to modify the x-value of variable a?
You can do simply as follows in derived class
void something(){ x = 1;}
Demo: http://coliru.stacked-crooked.com/a/b0f6153abfe6b783
When inheriting, b can modify the values of the base class "it" inherited, but the base abc protected class attributes of other objects are still protected and reserved for themselves. In this case the abc a object you pass through the function something is another object not associated with an object b.
Access modifiers work on class level, meaning within an object b the private attributes of another object b can be accessed. However, this inheritance shown is basically saying that "b is an abc, but abc isn't necessarily b". In the function void something(abc a){ a.x = 1;}, if you change it to something(b a) instead, it would work, because a b can access another b.
However, remember that if:
int main(){
abc data;
abc data2;
data.x = data2.x; //This won't work becuase you are outside the class
}
What you can do is declaring class b a friend of class abc, so that any object b can access the protected members of any other object abc.
Example:
class abc{
protected:
int x;
friend class b;
};
Within something() you are in object scope, so you have a pointer to the current object with the this keyword. In C++, however, the default resolution within object scope, is the object's own scope, so you don't need to prefix it at all. Simply referring the property's name is enough to have the resolution succeed.
One way to do what you are asking is to have a function setX() in class ABC like such:
class abc
{
public:
void setX(int x){ this->x = x; }
protected:
int x;
};
Then declare something inside of class B like this:
class b: public abc
{
public :
void something(abc a){ a.setX(1); }
};
At that point though you might as well not have class B at all, but rather from the scope you are calling b.something(myABCObj) just call myABCObj.setX(1) instead.
The point of 'protected' is that class b has access to 'x' in class abc not through the parameter you are passing it but rather inside of itself.
For example, your class b could look like this:
class b: public abc{
public :
void something(){ x = 1; } //HA- I inherited a value from class abc that wasn't public and changed it!
};
So in a different scope you could create object b myB; and myB.x won't be allowed but myB will have access to 'x' inside of itself from its parent class.

calling copy-constructor after simple inheritance

I have a doubt regarding some concept of inheritance, i am stating what i know, please correct me if i am wrong.
Private members of base class are inherited by the derived class but derived class can't access them by any means.
Protected members of base class are inherited by the derived class but derived class can't access it directly, but by the help of some of its member functions.
Now in the following code:
class A
{
protected:
A(const A&){}
A operator=(const A &){}
int t;
public:
A(int r) {t=r;}
A(){t=0;}
};
class B : public A
{
A a;
public:
void make(void)
{
//A b(a); //LINE 1 -------COPY CONSTRUCTOR BEING CALLED ---protected member of base class
cout<<t; //LINE 2 -------protected member of base class
}
};
int main()
{
B b;
b.make();
return 0;
}
Why there is error for LINE 1 coming??
Why we can't call copy-constructor for object of A?
Many many thanx in advance
A protected member can only be accessed by other members of the same complete object, during construction, destruction, or via the this pointer(*).
In your example class hierarchy, a B object has two subobjects of type A:
The base class subobject, which it gets by deriving from A, and
The data member subobject named a, which it gets by declaring a.
A member of B may only access protected members from the first A subobject, not from the second, because only the first directly uses the this pointer (note that your expression cout << t is semantically equivalent to cout << this->t).
Access to the members of the data member do not directly use the this pointer: if you tried to access this->a.t from B::make, the this pointer is not used directly to access the t. In your declaration A b(a);, the copy constructor is called not for this, but for the new A object you are constructing, the local variable named b.
(*) Or, of course, by any member in the class that declares it: any member function of B can call any other member function of B

How to access protected base class function, from derived class through base class ptr

I have abstract class A, from which I inherit a number of classes. In the derived classes I am trying to access protected function in A trough A pointer. But I get a compiler error.
class A
{
protected:
virtual void f()=0;
};
class D : public A
{
public:
D(A* aa) :mAPtr(aa){}
void g();
protected:
virtual void f();
private:
A* mAPtr; // ptr shows to some derived class instance
};
void D::f(){ }
void D::g()
{
mAPtr->f();
}
The compiler error says : cannot access protected member A::f declared in class A.
If I declare mAPtr to be D*, instead A* everything compiles. And I don't understand why is this.
Relying on private access works on unrelated instances of the same type.
Relying on protected access works on unrelated instances of the same type (and of more derived types).
However, relying on protected access does not work on unrelated instances of a base type.
[n3290: 11.5/1]: When a friend or a member function of a derived
class references a protected nonstatic member function or protected
nonstatic data member of a base class, an access check applies in
addition to those described earlier in clause 11. Except when forming
a pointer to member (5.3.1), the access must be through a pointer
to, reference to, or object of the derived class itself (or any class
derived from that class) (5.2.5). If the access is to form a pointer
to member, the nested-name-specifier shall name the derived class (or
any class derived from that class).
So D or something derived from D, but not A.
It's an oft-questioned cute oddity about C++ that nonetheless is designed to try to avoid pitfalls. After all, you don't know what type *mAPtr really has.
A class containing a protected section means that this class allows derived classes to manipulate their base class in any way they choose (as far as the protected interface allows).
Class D objects can manipulate their own A part. In doing say they probably want to maintain some invariants.
Suppose there is (or will be in the future!) another class E, also inherited from A. Class E objects also can manipulate their own A part, and they may be enforcing different invariants.
Now, if a class D object was allowed to manipulate the A part of any object, it can't ensure the invariants. A D object may do something to the A part of an E object that breaks that E object. That's why it is not allowed.
But if you really want to, perhaps a way to call A::f, without exposing it to everybody, would be via a friend function.
class A;
namespace detail
{
void call_f(A*);
}
class A
{
friend void detail::call_f(A*);
private:
virtual void f() = 0;
};
namespace detail
{
void call_f(A* a) { a->f(); }
}
class D: public A
{
public:
void g() { detail::call_f(mAPtr); }
private:
void f() {}
A* mAPtr;
};
This relies on users being disciplined enough to stay out of namespaces whose name clearly indicates that it contains implementation details.
You forgot using ; after class declaration:
class A
{
protected:
virtual void f()=0;
};
class D : public A
{
public:
void g();
protected:
void f();
private:
A* mAPtr; // ptr shows to some derived class instance
};
Besides, you don't need to store base class pointer.