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.
Related
So in my current understanding of how to use encapsulation correctly it is a good rule of thumb to make variables private and access them through member functions of the class like this:
class Aclass{
private:
int avar;
public:
void ch_avar(int val){avar = val};
int get_avar() {return avar;}
};
My question is how would I access a private member of a class instance which is its self a private member of another class. Here is an example of the way I have been trying to do it (not retyping the example above for brevity)
class LargerClass{
private:
int other_var;
Aclass A; //has two instances of class "Aclass"
Aclass B;
public:
void ch_other_var(int val){other_var = val;}
int get_other_var() {return other_var;}
// this is the important line for the question
int get_avar(Aclass X){return X.get_avar();}
};
Now In my real program there are a few more levels of this and I keep getting the compilation error that "Aclass" is an unknown type. Even though I have included the header file for Aclass in the Larger class. Since I am stuck I thought It would be good to find out if this is even the correct (or an acceptable way) of doing what I want. I am new to OOP and this feels sloppy to me.
To access the private member of a class instance which is its self a private member of another class, can be done this way. You don't need to pass a Aclass X. It is unneccessary. You can call it by the instance name you have given..
class LargerClass{
private:
int other_var;
Aclass A; //has two instances of class "Aclass"
Aclass B;
public:
void ch_other_var(int val){other_var = val;}
int get_other_var() {return other_var;}
// this is the important line for the question
int get_avar_A(){return A.get_avar();}
};
If you have 20 instances of Aclass, rather you create a vector of Aclass instances.
class LargerClass{
private:
int other_var;
Aclass A[20];
public:
void ch_other_var(int val){other_var = val;}
int get_other_var() {return other_var;}
// this is the important line for the question
int[] get_avar_A()
{
int other_var[20];
for(int i= 0; i<20; i++)
{
other_var[i] = A[i].get_avar();
}
return other_var;
}
};
This is a question to find out the better programming practice:
In C++, say I have two classes one of which is a member class of the other, e.g.,
class SomeClass {
public:
MemberClass member_class;
void set_num(double num_) { num_ = num; }
double num() {return num_; }
private:
double num_;
}
I want the member class to have access to the member functions of the outer class, e.g.,
class MemberClass {
public:
PrintSquare() {
cout << num() * num() << endl;
}
}
I am trying to achieve this in order to reduce the number of function arguments I am passing all around the program.
The most common (and IMHO proper) way to solve this problem is, introducing an interface (or even more interfaces focusing on particular sets of method features) for the containing class, and pass that one to the 'inner' class member on construction:
struct Interface {
virtual void set_num(double num_) = 0;
virtual double num() const = 0;
virtual ~Interface() {}
};
class MemberClass {
public:
MemberClass(Interface& interface) : interface_(interface) {}
PrintSquare() {
cout << interface_.num() * interface_.num() << endl;
}
private:
Interface& interface_;
};
class SomeClass : public Interface {
public:
MemberClass member_class;
SomeClass() : member_class(*this), num_() {}
virtual void set_num(double num_) { num_ = num; }
virtual double num() const { return num_; }
virtual SomeClass() {}
private:
double num_;
};
NOTE:
Calling methods of the interface though will fail (with a runtime exception), when called from the MemberClass constructor definition.
Although the answer by Kerrek is very interesting, he himself already states this normally isn't the way to go. Common practice would be to make the inner class nested in the outer one, if possible. If the inner one needs access to the outer one in such a way that a nested connection seems natural, this would be the way to go. Construction of an Inner object would then need a reference to the object it is a member from, in order to be able to call functions on its parent:
class Outer
{
class Inner
{
Outer &parent; // consider constness
public:
Inner(Outer &_parent); //initializes the parent-reference
void innerFunction(); // can call members of parent
};
Inner inner;
public:
Outer(): inner(*this) { ... } // initialize inner
};
Depending on the standard you're using, the innerFunction now has access to all public members of Outer (C++03), or even all private members as well (C++11). See also this topic:
C++ nested classes - inner/outer relationship
EDIT: Did a quick test, and my compiler (gcc 4.7.2) also allows access to private members with older standards. Maybe someone could comment on this...
If your classes are all standard-layout, then you can take advantage of some layout guarantees that C++ makes, namely that a on object of standard layout type may be treated as if it were its own first member. For instance:
struct Foo
{
int a;
void barely_legal();
};
struct Bar
{
Foo x;
int y;
};
#include <type_traits>
void Foo::barely_legal()
{
static_assert(std::is_standard_layout<Foo>::value, "Foo");
static_assert(std::is_standard_layout<Bar>::value, "Bar");
Bar * p = reinterpret_cast<Bar *>(this);
++p->y;
}
This is unusual at best and cruel at worst, so please don't write code like this unless you have a really good reason to do so. (I know people who do have reason to do this, but I don't turn my back towards them.)
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();
};
I am not able to find a similar question else where on this site, but is it possible to declare a class over two different files.
for example, all public class components in a file and privates and others in a different file.
publics.h
class test {
public:
int geta();
void seta(int);
};
privates.h
class test {
private:
int a;
};
The above way is definitely wrong, but is there any such method.
There is a way to get something quite similar: private inheritance.
// private.hpp
class test_details {
protected:
int a;
};
// public.hpp
#include "private.hpp"
class test : private test_details {
public:
int geta() const { return a; }
void seta(int i) { a = i; }
};
Note that you will still need to (indirectly) include the private header in any module that uses the public class, so you're not really hiding anything this way.
Not like that, but the pimpl idiom (or opaque pointer, or Chesshire cat) can help you achieve similar functionality - you can provide a public interface where all implementation details are hidden in an implementation member.
C++ doesn't support partial classes.
Also, note that what you have there are class definitions, not declarations. C++ mandates that if multiple definitions of a class are available, they must be identical, otherwise it's undefined behavior.
This is a good use case for an abstract base class
//File test.h
class test {
public:
virtual ~test() {}
virtual int geta()=0;
virtual void seta(int)=0;
};
//File test_impl.h
class test_impl : public test {
public:
int geta() { return a; }
void seta(int a ) { a = v; }
private:
int a;
};
I have a class (class A) that is designed to be inherited by other classes written by other people.
I also have another class (class B), that also inherits from A.
B has to access some A's member functions that shouldn't be accessed by other inheriting classes.
So, these A's member functions should be public for B, but private for others.
How can I solve it without using 'friend' directive?
Thank you.
EDIT: Example why I need it.
class A
{
public:
void PublicFunc()
{
PrivateFunc();
// and other code
}
private:
virtual void PrivateFunc();
};
class B : public class A
{
private:
virtual void PrivateFunc()
{
//do something and call A's PrivateFunc
A::PrivateFunc(); // Can't, it's private!
}
};
You can't. That's what friend is for.
An alternative would be to change the design/architecture of your program. But for hints on this I'd need some more context.
What you say is: there are two sets of subclasses of A. One set should have access, the other set shouldn't. It feels wrong to have only one brand of subclasses (i.e. B) 'see' A's members.
If what you mean is: only we can use this part of functionality, while our clients can't, there are other resorts.
(Functionality reuse by inheritance often corners you with this kind of problems. If you go towards reuse by aggregation, you may get around it.)
A suggestion:
// separate the 'invisible' from the 'visible'.
class A_private_part {
protected:
int inherited_content();
public:
int public_interface();
};
class B_internal : public A_private_part {
};
class A_export : private A_private_part {
public:
int public_interface() { A_private_part::public_interface(); }
};
// client code
class ClientClass : public A_export {
};
But better would be to go the aggregation way, and split the current "A" into a visible and an invisible part:
class InvisibleFunctionality {
};
class VisibleFunctionality {
};
class B {
InvisibleFunctionality m_Invisible;
VisibleFunctionality m_Visible;
};
// client code uses VisibleFunctionality only
class ClientClass {
VisibleFunctionality m_Visible;
};
Well - if you want exactly what you've described, then friend is the best solution. Every coding standard recommends not using friend but where the alternative design is more complex - then maybe it's worth making an exception.
To solve the problem without friend will require a different architecture
One solution might be to use a form of the pImpl idiom where 'B' derives from the inner implementation object, while the other clients derive from the outer class.
Another might be to place an extra layer of inheritance between 'A' and the "other clients". Something like:
class A {
public:
void foo ();
void bar ();
};
class B : public A { // OK access to both 'foo' and 'bar'
};
class ARestricted : private A {
public:
inline void foo () { A::foo (); }; // Forwards 'foo' only
};
However, this solution still has it's problems. 'ARestricted' cannot convert to an 'A' so this would need to be solved by some other "getter" for 'A'. However, you could name this function in such a way as it cannot be called accidentally:
inline A & get_base_type_A_for_interface_usage_only () { return *this; }
After trying to think of other solutions, and assuming that your hierarchy needs to be as you describe, I recommend you just use friend!
EDIT: So xtofl suggested renaming the types 'A' to 'AInternal' and 'ARestricted' to 'A'.
That works, except I noticed that 'B' would no longer be an 'A'. However, AInternal could be inherited virtually - and then 'B' could derive from both 'AInternal' and 'A'!
class AInternal {
public:
void foo ();
void bar ();
};
class A : private virtual AInternal {
public:
inline void foo () { A::foo (); }; // Forwards 'foo' only
};
// OK access to both 'foo' and 'bar' via AInternal
class B : public virtual AInternal, public A {
public:
void useMembers ()
{
AInternal::foo ();
AInternal::bar ();
}
};
void func (A const &);
int main ()
{
A a;
func (a);
B b;
func (b);
}
Of course now you have virtual bases and multiple inheritance! Hmmm....now, is that better or worse than a single friend declaration?
I think you have a bigger problem here. Your design doesn't seem sound.
1) I think the 'friend' construct is problematic to begin with
2) if 'friend' isn't what you want, you need to re-examine your design.
I think you either need to do something that just gets the job done, using 'friend' or develop a more robust architecture. Take a look at some design patterns, I'm sure you'll find something useful.
EDIT:
After seeing your sample code, you definitely need to re-arch. Class A may not be under your control, so that's a little tricky, but maybe want you want to re-do Class B to be a "has-a" class instead of an "is-a" class.
public Class B
{
B()
{
}
void someFunc()
{
A a; //the private functions is now called and a will be deleted when it goes out of scope
}
};
I find this a interesting challenge. Here is how I would solve the problem:
class AProtectedInterface
{
public:
int m_pi1;
};
class B;
class A : private AProtectedInterface
{
public:
void GetAProtectedInterface(B& b_class);
int m_p1;
};
class B : public A
{
public:
B();
void SetAProtectedInterface(::AProtectedInterface& interface);
private:
::AProtectedInterface* m_AProtectedInterface;
};
class C : public A
{
public:
C();
};
C::C()
{
m_p1 = 0;
// m_pi1 = 0; // not accessible error
}
B::B()
{
GetAProtectedInterface(*this);
// use m_AProtectedInterface to get to restricted areas of A
m_p1 = 0;
m_AProtectedInterface->m_pi1 = 0;
}
void A::GetAProtectedInterface(B& b_class)
{
b_class.SetAProtectedInterface(*this);
}
void B::SetAProtectedInterface(::AProtectedInterface& interface)
{
m_AProtectedInterface = &interface;
}
If you where going to use this sort of pattern all the time, you could reduce the code by using templates.
template<class T, class I>
class ProtectedInterfaceAccess : public I
{
public:
void SetProtectedInterface(T& protected_interface)
{
m_ProtectedInterface = &protected_interface;
}
protected:
T& GetProtectedInterface()
{
return *m_ProtectedInterface;
}
private:
T* m_ProtectedInterface;
};
template<class T, class I>
class ProtectedInterface : private T
{
public:
void SetupProtectedInterface(I& access_class)
{
access_class.SetProtectedInterface(*this);
}
};
class Bt;
class At : public ProtectedInterface <::AProtectedInterface, Bt>
{
public:
int m_p1;
};
class Bt : public ProtectedInterfaceAccess<::AProtectedInterface, At>
{
public:
Bt();
};
class Ct : public At
{
public:
Ct();
};
Ct::Ct()
{
m_p1 = 0;
// m_pi1 = 0; // not accessible error
}
Bt::Bt()
{
SetupProtectedInterface(*this);
m_p1 = 0;
GetProtectedInterface().m_pi1 = 0;
}
If I understand:
A will be subclassed by other developers.
B will be subclassed by other developers and inherits from A.
A has some methods you don't want accessible to outside developers through B.
I don't think this can be done without using friend. There is no way I know of to make members of a superclass available only to direct inheritors.