There is one file with two separate classes and one function:
int foo(int x) {return x+x;}
class A {
public:
int bar(){return foo(0);}
};
class B {
public:
int bar(){return foo(1);}
};
and they both need to use function
which uses only its argument (not use any data from A or B).
I can declare this function as global. But i would like to hide this function for other files (so this is un visible, unacccesible in other files). So i can declare this function as member function of each class A and B. But this will be code duplicate.
What is the best practice for that?
You can just omit any declarations of foo from any headers, and mark it static or define it in an anonymous namespace.
AB.h
class A { int bar(); };
class B { int baz(); };
AB.cpp
static int foo(int x) { return x+x; }
/* or
namespace {
int foo(int x) { return x+x; }
}
*/
int A::bar() { return foo(1); }
int B::baz() { return foo(2); }
You can simply place the function inside another class that only exists in that file:
class C
{
public:
static void foo(int) {}
};
class A
{
void test1()
{
C::foo(0);
}
};
class B
{
void test2()
{
C::foo(0);
}
};
A & B can access this function now and it's not being declared globally.
You can also put the function in its own namespace:
namespace ABFunctions
{
void foo(int) {}
}
And that is another way of keeping it separated, logically.
If you need to protect access, you can do it this way:
class C
{
friend class A;
friend class B;
private:
static void foo(int) {}
};
class A : C
{
void test1()
{
C::foo(0);
}
};
class B : C
{
void test2()
{
C::foo(0);
}
};
Now, only class A & B will have access to foo(int).
You can create a base class and derive from it. You won't have to duplicate code.
class Base {
virtual ~Base = 0;
protected:
int foo(int x) {return x+x;}
};
class A : public Base {...}
class B : public Base {...}
You can't instantiate an object of Base.
If it does not use any data from A or B, then it probably shouldn't be implemented within A or B. It sounds as if f was some kind of auxiliary function. Perhaps creating a class Utilities and making it a public static function of the utilities class would be better.
In c++ there's no hiding of functions at namespace level, though you can create a utility class that contains only private static functions, and explicitly specify which classes may have access using the friend keyword:
class C {
friend class A;
friend class B;
static void foo(int);
};
int foo(int x) {return x+x;}
class A {
public:
int bar(){return C::foo(0);}
};
class B {
public:
int bar(){return C::foo(1);}
};
Though that's not a very good design pattern, since friend introduces some more maintenance effort, as soon other classes than A or B need to access foo as well.
A probably better pattern is to use an interface as I've sketched out in my Q&A here:
How can I remove/refactor a «friend» dependency declaration properly?
The introduction of interfaces there suffers from the overhead of virtual polymorphism though. Maybe that could be resolved with introduction of static polymorphism via the CRTP.
Regarding a wider view for maintenance and reusing implementation details, why are you trying to hide these as rigorously claimed for the function foo(). Why do you need to hide this implementation detail at all?
Related
class A{
public:
void printer(){
B obj;
obj.private_data = 10; // <- fails, says member inaccessible
}
}
class B{
friend void A::printer();
private:
int private_data;
}
is it possible for printer function to access private members of class B? i tried to pass an obj of B as arg to printer but it still failed
Class A doesn't know about B to use it. Hence, postpone the definition of the function printer() until you define B, and if you need an instance of B to be a member var in A then make a forward declaration for B to declare a B* in A.
Hence, use something like what follows:
class A {
public:
void printer();
};
class B {
friend void A::printer();
private:
int private_data;
};
void A::printer() {
B obj;
obj.private_data = 10; // <- No longer fails
std::cout << obj.private_data;
}
int main() {
A a;
a.printer();
}
Demo
Why Friend Function cannot access private members of a class?
They can, but you may need to split the definition of the class up a bit.
Imaginary files added:
Define A (file a.hpp):
class A {
public:
void printer();
};
Define B (file b.hpp):
#include "a.hpp" // B must see the definition of A to befriend a member function
class B {
friend void A::printer();
private:
int private_data;
};
Define A's member function (file a.cpp):
void A::printer() {
B obj;
obj.private_data = 10;
}
To access B, you first need to define it. Thus, you can just declare the method printer and define it after you have defined the class B.
class A {
public:
void printer();
};
class B {
private:
friend class A;
int private_data;
};
void A::printer() {
B obj;
obj.private_data = 10;
}
Note, you probably want to move your methods out of your class definition anyways and into a separate .cpp file. Methods defined inside the class are implicitly marked as inline which might not be what you expect.
I am not sure how to ask this, but hopefully someone will understand. Lets say I have 3 different classes. Class A, Class B and Class C. Class C should take either Class A or Class B as a parameter in the constructor and store it in a private variable.
This is easy with overloaded constructors. My question is how can Class C automagically use the correct class depending on what constructor was used? (Note these 2 classes are similar, but come from different libraries and thus no shared base class). Is this possible with templates? I do not have a lot of experience with templates.
You can do it quite easy with templates:
class A;
class B;
template<class AorB>
class C
{
public:
C(AorB aorb)
: aorb_(aorb)
{ }
private:
AorB aorb_;
};
What this does is that inside the class C the identifier AorB can be used as any other class, in fact it doesn't even have to be an instance of A or B but can be any class.
Can be used like this:
A myA;
B myB;
C<A> myCWithA(myA);
C<B> myCWithB(myB);
There is however one thing you have to remember when creating classes using templates: The specification and implementation can no longer be split into separate header and source files. All of the code have to be available in the header file.
The syntax of the member functions are also a little different.
Example:
template<class T>
class C
{
public:
...
void someFunction();
};
template<class T>
C<T>::someFunction()
{
...
}
Yes, this is possible with templates:
#include <iostream>
template<class T>
class C {
public:
C(T const& ref) : ref(ref) {}
void doStuff() const {
ref.doStuff();
}
private:
T ref;
};
class A {
public:
void doStuff() const {
std::cout << "A::doStuff" << std::endl;
}
};
class B {
public:
void doStuff() const {
std::cout << "B::doStuff" << std::endl;
}
};
int main() {
C<A> foo((A()));
foo.doStuff();
C<B> bar((B()));
bar.doStuff();
}
Suppose we have two classes:
class Base
{
private:
int x;
public:
void f();
};
class Foo
{
// some variables and methods
};
Now everyone can call Base::f(), but I want only Foo to be able to do so.
In order to achieve this effect, we can make Base::f() private and declare Foo as a friend:
class Base
{
private:
int x;
void f();
friend Foo;
};
The problem with this approach is that Foo has the access to both Base::f() and Base::x (and even to any other private members of Base). But I want Foo to have access only to Base::f().
Is there a way for a class (or a function) to grant an access only to certain private members of another class? Or maybe anyone could suggest a better approach to my problem?
EDIT:
I'll try to specify the access restriction I need. Firstly, Base is an interface in a library (it's an abstract class, in fact). The user uses only the classes derived from Base. Base::f() is called only by Foo which is another class in the library. Hiding Base::f() from the user is important, because only Foo knows when to call it. At the same time, Foo shouldn't mess up the other members of Base.
Very hacky, but this will allow very fine grained access.
class Base
{
private:
int x;
void f();
friend class Base_f_Accessor;
};
class Base_f_Accessor
{
private:
static void f(Base & b) { b.f(); }
friend class Foo;
}
class Foo
{
// some variables and methods
};
You can create another class that contains the data for Base like this:
class BaseData {
protected:
int x;
};
class Base : public BaseData {
friend class Foo;
void f ();
};
Now, Foo can access f as a method of Base like you wanted, but not x. Friendship is not commutative. By using protected, x appears private to everyone except those that derived directly from BaseData.
A better approach might be to use multiple inheritance to define Base, and provide Foo access only to those classes you want from which Base derives.
class With_f {
friend class Foo;
protected:
virtual void f () = 0;
};
class With_g {
protected:
virtual void g () = 0;
};
class Base : public With_f, public With_g {
int x;
void f () {}
void g () {}
};
Here, Foo would have to have a With_f pointer to Base, but it could then access the f method. Foo could not access g.
There's no easy, non-hackish way to achieve that. C++ simply doesn't have such access control granularity. You can play with some inheritance, but increased complexity outweighs any advantages this access restriction might have. Also, this approach doesn't scale - you can grant increased permissions only to one friend class.
Maybe a bit cumbersome, but you could make nested classes where the nesting class is friend, then you can add friends per nested class. This gives some level of granularity:
#include <iostream>
class Nesting
{
friend class Foo;
class Nested1
{
friend class Nesting;
public:
Nested1() : i(3) { }
private:
int i;
} n1;
class Nested2
{
friend class Nesting;
friend class Foo;
public:
Nested2() : j(5) { }
private:
int j;
} n2;
int f() { return n1.i; }
};
class Foo
{
public:
Foo(Nesting& n1) : n(n1) { }
int getJ() { return n.n2.j + n.f(); }
private:
Nesting& n;
};
int main()
{
Nesting n;
Foo foo(n);
std::cout << foo.getJ() << "\n";
}
Suppose an object of class B is a member of class A.
class B{
//Definitions
}
class A{
public:
A();
B b_child;
int some_function();
}
One of the functions defined inside B needs to call a (public) function from its owner (parent?) A. Is there an immediate way to do this?
The only way I've managed to do this so far was to implement it outside the classes' definitions:
A a_obj;
a_obj.b_child.setowner(&aobj);
which tells b_child who is its owner. I don't like this. I'd rather use some builtin method for b_child to access its parent (if possible). If that's not possible, I'd rather pass the owner's address directly in the constructor for B, but I don't know how to reference A's address inside its definition.
There is no builtin method to get the 'owner' of a variable, whatever that means. Your approach of setting the owner is correct. Furthermore, doing so in the construction of B is also a correct decision. Sample code:
class B
{
public:
explicit B( A* owner ) : _owner( owner ) {}
...
private:
A* _owner;
};
class A
{
public:
A() : _child( this ) {}
...
private:
B _child;
};
Note some compilers may give you a warning for using this in that context, but its ok for the current example. Just make sure you don't call any A member functions from within B constructor, since the pointer you get still points to an unconstructed object at that stage.
I'd rather use some builtin method for b_child to access its parent (if possible).
No, it's not.
but I don't know how to reference A's address inside its definition.
You can use this pointer.
A() : b_child(this) { }
You should use this pointer to refer to the object within itself
class B{
//Definitions
}
class A{
private:
B b_child;
public:
A()
{
b_child.set_owner(this);
}
}
You should define B like the following:
template <class T, int N>
class B
{
public:
int example_func() { return static_cast<T&>(*this).some_function(); }
};
And then make B<A> a subclass of A (so it can call A directly).
class A : protected B<A,0>, protected B<A,1>
{
A();
int some_function() { return 42; }
};
This is called the curiously recurring template pattern.
If you don't want B to be a template class, and you're only going to use B with A, then the following is fine:
template <int N>
class B
{
public:
int example_func() { return static_cast<A&>(*this).some_function(); }
};
class A : protected B<0>, protected B<1>
{
A();
int some_function() { return 42; }
};
Alternatively, if you want to use B with not just A, but don't want to make B a template class (say, if you want a collection of pointers to B), you can do the following:
template <int N>
class B
{
public:
int example_func() { return some_function(); }
virtual int some_function() = 0;
};
class A : protected B<0>, protected B<1>
{
A();
int some_function() { return 42; }
};
This will resolve the some_function() call at run-time, and require a virtual pointer to be stored in your class.
I have a linked list of Foo objects. Foo is a base class, which has several classes inherit from it. Say, classes A, B, and C.
I am cycling through this linked list and calling a method some_method, which has 3 definitions; one for each child class:
some_method(A a);
some_method(B b);
some_method(C c);
The linked list is generic, so it is of type Foo, as it has an assortment of A, B and C objects.
When I'm cycling through the linked list at current_element, calling some_method(current_element);, how can I make it call the right method? The compiler complained until I wrote a some_method that took the generic Foo, and it only calls into that method.
Depending on your requirements, you may want to consider using polymorphism. To do this, add a pure virtual method to your base node class, and move the corresponding methods to the derived classes.
class Foo
{
public:
virtual void some_method() = 0;
};
class A : Foo
{
public
virtual void some_method()
{
// move the body of some_method(A a) here
}
};
For this to work, your linked list will need Foo*, instead of Foo.
class Node
{
public:
Foo* foo;
Node* next;
};
// ...
Node* someNode = GetNode();
// Calls correct method - A::some_method, B::some_method, or C::some_method
someNode->foo->some_method();
If you can't put some_method in Foo/A/B/C, then you might want to look into the Visitor design pattern:
http://en.wikipedia.org/wiki/Visitor_pattern
This is the "double dispatch" problem. You can use the visitor pattern. Usually the Visitor is a base class so you can re-use this design for multiple problems.
#include <iostream>
class FooVisitor;
class Foo
{
public:
virtual void some_method() = 0;
virtual void visit(FooVisitor* v) = 0;
};
class A;
class B;
class FooVisitor
{
public:
virtual void visit(A* a){ std::cout << "A" << std::endl;}
virtual void visit(B* b){std::cout << "B" << std::endl;}
};
class A : public Foo
{
public:
virtual void some_method()
{
// move the body of some_method(A a) here
}
virtual void visit(FooVisitor* v) { v->visit(this);}
};
class B : public Foo
{
public:
virtual void some_method()
{
// move the body of some_method(A a) here
}
virtual void visit(FooVisitor* v) { v->visit(this);}
};
int main()
{
FooVisitor fv;
Foo* f1 = new A;
f1->visit(&fv);
Foo* f2 = new B;
f2->visit(&fv);
getchar();
}
Two ways:
1) the better way:
Reverse your design such that someMethod is a virtual method of the base class Foo and redefine it in the derived classes. As:
class Foo {
public:
virtual void someMethod() = 0;
};
class A {
public:
void someMethod() { /* implementation specific to A here */ };
};
class B {
public:
void someMethod() { /* implementation specific to B here */ };
};
class C {
public:
void someMethod() { /* implementation specific to C here */ };
};
Then calling the someMethod on a pointer to Foo will automatically call the method from the appropriate class. If that cannot be done because someMethod cannot be implemented as part of Foo or its derivatives (e.g. it needs access to private members of the class it is currently in in your design), then you might try to split this functionality apart into subproblems that can be put into virtual methods of these classes A B C.
2) the "I don't have a choice" way:
Use RTTI (Run-Time Type Identification), it is included in C++. It requires that your base class Foo has at least one virtual method. You need to #include <typeinfo>, then use typeid() on the pointer, it will return a type_info object, and you can compare its name() result with the class names A B and C. This isn't a very nice approach because it has more overhead and it breaks OOP design principles. But if that's the only option, it's fine.
RTTI is your friend here. The example given in the link will guide you further
You can call the method for the child class as a member method. For exampleA a = new A(); a.some_method() should call the correct the method. Within some_method() you can reference to object using keyword this.