In C++, one can have (please forgive errors as I haven't done C++ in a while and corrections are appreciated):
class Super {
private: virtual void g() = 0;
public: void f() {
g();
}
};
class Sub: public Super {
private: virtual void g() {
}
};
such that Sub defines g but cannot call it directly.
Can the same thing be done in Scala?
If you try it like this
abstract class Super {
private def g()
def f() {
g()
}
}
the compiler will give you this error messge:
scala: abstract member may not have private modifier
private def g()
You have to declare g() at least protected.
I think the closest thing is
abstract class Super {
protected[this] def g: Int
def f { println(g) }
}
class Sub extends Super {
protected[this] def g = 5
}
but this does not give Super any more access rights than Sub; it just prevents Sub from calling that method on other instances.
The exact same pattern is not possible in Scala. (It would have to be a compiler fiction, as the JVM doesn't support it, but many of the access patterns are already compiler fictions.)
Related
class MyInterface {
public:
virtual void someFunction()= 0;
};
class X: public MyInterface {
private:
virtual void doThis() {
printf("This X");
}
virtual void doThat() {
printf("That X");
}
public:
void someFunction() {
doThis();
doThat();
}
};
class Y: public MyInterface, private X {
private:
void doThat() {
printf("That Y");
}
};
MyInterface *iface= new Y();
Y->someFunction();
Coming from Java's flavor of OOP, I am trying to wrap my head around the OOP model of C++. I have read this: http://www.gotw.ca/publications/mill18.htm for suggestions how to design interfaces in C++. The above code is a direct application (or a slight variation thereof) of the rule the author expounds. My question is, is the code above going to produce "This X" followed by "That Y"? What I find confusing is that the author recommends using virtual in conjunction with private. My reasoning is, if a function is private, how are we to override it at all?
In the above code, it is granted that Y can be used as the right-hand-side of the assignment, since we derive publicly from the interface. When we call someFunction() on it, since we do not explicitly provide any implementation inside class Y, is it going to use the implementation from class X? Then, provided it does, it looks at doThat() and again uses Ys implementation of it?
The code has a few problems. Here is a working example:
class MyInterface
{
public:
virtual ~MyInterface() { }
virtual void someFunction() = 0;
};
class X : public MyInterface
{
private:
virtual void doThis()
{
printf("This X\n");
}
virtual void doThat()
{
printf("That X\n");
}
public:
void someFunction()
{
doThis();
doThat();
}
};
class Y : public X
{
private:
void doThat()
{
printf("That Y\n");
}
};
int main()
{
MyInterface *iface = new Y();
iface->someFunction();
delete iface;
}
Explanations
You need to use class Y : public X to be able to use the implementation of void X::someFunction()
Unfortunately there is no real interface in C++ and there is only a workaround using pure virtual class. This workaround with two parents has it's own limitations (see bellow). And therefore it is also a good idea to add a destructor to interface definition.
When you use class Y: public MyInterface, private X you need to provide a custom implementation of MyInterface::someFunction(). You have have two parent classes and someFunction() in both parents (X and MyInterface). This is necessary even when there is only one implementation of function. Therefore you need to specify which parent class 'implementation' will be used. Error:
'Y': cannot instantiate abstract class
You also get a error when you remove the interface (try to use the interface from X). The reason is simple, when X is private, the implementation is not public and can not be used as a interface.
'type cast': conversion from 'Y *' to 'MyInterface *' exists, but is inaccessible
You are using class as type in Y->someFunction();
I have no idea, why you can override a private virtual function. I mostly work in C# now and this 'feature' of C++ is something I do not get. You are right, that this should be bad code, but it work (at least in Visual Studio 2017).
I would also like to know, why this is not considered as error/incorrect code construction.
I have this structures in C++11
struct A {
int idA;
void setId(int i) { idA = i;}
int getId() { return idA;}
virtual void foo() = 0;
};
struct B {
int idB;
void setId(int i) { idB = i;}
int getId() { return idB;}
virtual void foo2() = 0;
};
struct AB : public A, public B
{
void foo() override {}
void foo2() override {}
};
Now in main I can call it like this:
AB * ab = new AB();
ab->B::setId(10);
but I dont really like it.
Is there any other solution? Methods setId/getId from struct A are not needed in AB. I just did the inheritance, because I need foo() and other stuff from A, but all other methods are unique.
Since you said that you don't need A's version of those methods, you could write
struct AB : public A, public B
{
void foo() override {}
void foo2() override {}
using B::setId;
using B::getId;
};
This will put B's implementation of those methods into AB's namespace and make calling them unambiguous.
What about wrapper forwarding methods:
struct AB : public A, public B
{
public:
void setAId(int i) { A::setID(i); }
void setBId(int i) { B::setID(i); }
};
That way you do not become "victim" of name hiding, your intent becomes clear in the code and you have the names that reflect what they do and you do not need to access the member(s) of base class(es) explicitely.
Alternatively you can create another base class and inherit it virtually in both A and B in which you would contain the setId method.
The accepted answer does work as long as you call setId(int) on an object of type AB or an AB pointer (most cases, surely). But if you want to call the function on A* ab = new AB(); you have to explicitly override it.
struct A {
int idA;
virtual void setId(int i) { idA = i;}
};
struct B {
int idB;
virtual void setId(int i) { idB = i;}
};
struct AB : public A, public B
{
void setId(int i) override { B::setId(i); }
};
I believe that both mine and the accepted answers introduces rather annoying problem, consider:
AB ab;
A *a = &ab;
a->setId(10); //problem
a->foo(); //calls AB::foo() correctly
When the name hiding is used (accepted answer) the AB object never gets called while my answer (wrapping the call) does not account for this either. The correct approach in this case in my opinion is to use private inehritance of A and exposing only foo(), so only one thing would change from original OP's code:
struct AB : private A, public B
Typically with OO and Inheritance, if functionality reuse is unknown at the time, it is typically better to implement the function several times until you determine a pattern that will allow you to break it apart.
For instance, there is nothing wrong with having a class object being a container of data and inherriting from it.
class IdentificationData {
int ID;
. . .
}
You also do not necessarily need to have functions be part of a class. A class is simply a container, and is used to organize and encapsulate data, functions that may operate on the data, or a collection of functions into one common set.
class IdentificationFunctionality{
static SetID( IdentificationData* obj) {...}
}
Doing this will then allow you to do something like...
class AB: IdentificationData, B {
. . .
}
AB* ab = new AB();
IdentificationFunctionality::SetID(&ab);
The other benefits to this, is this will allow you to do some book keeping without your objects needing to know the details of the data-banking system.
I have a class (let's call it A) the inherits an interface defining several abstract methods and another class there to factor in some code (let's call it B).
The question is, I have an abstract method in the interface that A implements just to call the B version. Is there a way to use the keyword using to avoid writing a dull method like:
int A::method() override
{
return B::method();
}
I tried writing in A using B::method, but I still get an error that A doesn't implement the abstract method from the interface.
Is there a special technique to use in the case or am I just out of luck? (and if so, is there a specific reason why it should be that way?).
Thanks.
edit:
To clarify, the question is, why isn't it possible to just do this:
class A: public Interface, public B {
using B::method;
};
Let's make this clear. You basically have the following problem, right?
struct Interface
{
virtual void method() = 0;
};
struct B
{
void method()
{
// implementation of Interface::method
}
};
struct A : Interface, B
{
// some magic here to automatically
// override Interface::method and
// call B::method
};
This is simply impossible, because the fact that the methods have the same names is irrelevant from a technical point view. In other word's, Interface::method and B::method are simply not related to each other, and their identical names are not more than a coincidence, just like someone else called "Julien" doesn't have anything to do with you just because you share the same first name.
You are basically left with the following options:
1.) Just write the call manually:
struct A : Interface, B
{
virtual void method()
{
B::method();
}
};
2.) Minimise writing work with a macro, so that you can write:
struct A : Interface, B
{
OVERRIDE(method)
};
But I would strongly recommend against this solution. Less writing work for you = more reading work for everyone else.
3.) Change the class hierarchy, so that B implements Interface:
struct Interface
{
virtual void method() = 0;
};
struct B : Interface
{
virtual void method()
{
// implementation of Interface::method
}
};
struct A : B
{
};
if B::method is abstract you cannot call it because is not implemented... has no code.
An example:
class A
{
public:
virtual void method1( ) = 0;
virtual void method2( ){ }
};
class B : public A
{
public:
virtual void method1( ) override
{ return A::method1( ); } // Error. A::method1 is abstract
virtual method2( ) override
{ return A::method2( ); } // OK. A::method2 is an implemented method
}
Even if there were a way to do what you want, in the name of the readability of your code, I would not recommend that.
If you do not put the "B::" before "method" call, when I read that, I would say it is a recursive call.
Have a interface
class abc {
public:
virtual int foo() = 0;
...
}
class concrete1: public abc {
public:
int foo() {
..
}
class concrete2 : public abc {
public:
int foo() {
..
}
}
Now in my main program I need to construct classes based upon a value of a variable
abc *a;
if (var == 1)
a = new concrete1();
else
a = new concrete2();
Obviously I don't want these two lines everywhere in the program (please note I have simplified here so that things are clear). What design pattern should I be using if there are any?
You are looking for http://en.wikipedia.org/wiki/Factory_method_pattern
First, you should use a factory or factory method as litb has mentioned.
But in addition to that I advise you to use an enum, or at least symbolic constants to determine which class to instantiate. This is much easier to read, and it allows you to build safeguards for unexpected values.
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.