I find that the dynamic method dispatching in init method of Swift is different from which in C++, can anyone explain why?
This is the demo code and its output:
In Swift:
class Object {
init() {
a()
}
func a() {
print("Object")
}
}
class SubObject: Object {
override init() {
}
override func a() {
print("SubObject")
}
}
let a = SubObject()
// output: SubObject
In C++:
class Object {
public:
Object() {
a();
}
virtual void a() {
std::cout << "Object" << std::endl;
}
};
class SubObject: public Object {
public:
SubObject() {
}
virtual void a() {
std::cout << "SubObject" << std::endl;
}
};
int main(int argc, const char * argv[]) {
SubObject s;
return 0;
}
// output: Object
As you can see, these code above write in Swift and C++ are nearly the same, but their output is quite different, while Swift seems that it finds the override method and called the derived one, the C++ still called the super's.
Here at LearnCpp, it says:
Do not call virtual functions from constructors or destructors Here’s another gotcha that often catches unsuspecting new programmers. You should not call virtual functions from constructors or destructors. Why?
Remember that when a Derived class is created, the Base portion is constructed first. If you were to call a virtual function from the Base constructor, and Derived portion of the class hadn’t even been created yet, it would be unable to call the Derived version of the function because there’s no Derived object for the Derived function to work on.
In C++, it will call the Base version instead.
A similar issue exists for destructors. If you call a virtual function in a Base class destructor, it will always resolve to the Base class version of the function, because the Derived portion of the class will already have been destroyed.
Related
In PHP there is a way of accessing a static property value that is defined/overridden on an inheritor.
e.g.
class Foo {
public static $name='Foo';
public function who(){
echo static::$name;//the static operator
}
}
class Bar extends Foo {
public static $name='Bar';
}
$bar = new Bar();
$bar->who();
//Prints "Bar";
Is there ANY way of doing the exact same thing in Dart language?
Addressing comments:
About making it instance prop/method: There's a reason for the existence of static properties and methods and it's not having to create a new instance of the object to access a value or functionality that is not mutable.
Yes, but that's not how you are using it. Your use case is to invoke the method on an object, and therefore you really want an instance method. Now, some languages automatically allow invoking class methods as instance methods, and I see two choices for a language that offers that ability:
Statically transform fooInstance.classMethod() to ClassFoo.classMethod() based on the declared type (not the runtime type) of the object. This is what Java and C++ do.
Implicitly generate virtual instance methods that call the class method. This would allow fooInstance.classMethod() to invoke the appropriate method based on the runtime type of the object. For example, given:
class Foo {
static void f() => print('Foo.f');
}
You instead could write:
class Foo {
static void classMethod() => print('Foo.f');
final instanceMethod = classMethod;
}
and then you either could call Foo.classMethod() or Foo().instanceMethod() and do the same thing.
In either case, it's syntactic sugar and therefore isn't anything that you couldn't do yourself by being more verbose.
About the "meaning of static" and "only work because they allow invoking class methods as instance methods" : That affirmation is actually wrong. In the case of PHP, as per the example above, the Language is providing a way to access the TYPE of the class calling the method in the inheritance chain. A(methodA) >B > C. When C calls methodA, PHP allows you to know that the class type you're in is indeed C, but there's no object instance attached to it. the word "static" there is a replacement for the caller class type itself
All of that is still known at compilation time. That C derives from B derives from A is statically known, so when you try to invoke C.methodA, the compiler knows that it needs to look for methodA in B and then in A. There's no dynamic dispatch that occurs at runtime; that is still compile-time syntactic sugar. That is, if you wanted, you could explicitly write:
class A {
static void methodA() {}
}
class B extends A {
static void methodA() => A.methodA();
}
class C extends B {
static void methodA() => B.methodA();
}
Anyway, in your example, you could write:
class Foo {
static String name = 'Foo';
String get nameFromInstance => name;
void who() {
print(nameFromInstance);
}
}
class Bar extends Foo {
static String name = 'Bar';
#override
String get nameFromInstance => name;
}
void main() {
var bar = Bar();
bar.who(); // Prints: Bar
}
let's assume i have a wrapper class that embeds a single memeber:
class wrapper {
public:
Object obj;
// the rest ...
};
if the member variable obj has some methods, how can i call the member variable method without explicitly defining methods in the wrapper class like this?
class wrapper{
public:
void foo { obj.foo (); }
int bar (int x) {return obj.bar(x); }
};
i know this is doable in python, but how can i have the same functionality in c++?
ps- please note i don't want to inherit from the member class. this wouldn't't be a wrapper class by definition. i want to achieve this through composition instead.
There are a few ways to handle this. One would be to create a getter to return the wrapper object and another is to override the typecast operator:
class Object {
public:
void foo() {cout << "test" << endl;}
};
class wrapper {
protected:
Object obj;
public:
operator Object&() {return obj;}
Object& getObject() {return obj;}
};
void f(A& a) {
a.foo();
}
int main() {
wrapper w;
((Object)w).foo();
w.getObject().foo();
f(w);
return 0;
}
As you can see, the typecast operator requires you to cast the wrapper object, except when passing as a parameter to the function f().
Also, in your example you already have the obj member as public so it is exposed. You could just:
wrapper w;
w.obj.foo();
Here's a discussion on that: What good are public variables then?
How can a method from the InterfaceBaseList be implemented in the current interface ? Example:
interface bar(T)
{
void method1(T a);
void method2(T a);
}
interface baz: bar!int
{
final void method1(int a){}
}
class foo: baz
{
this(){method1(0);}
void method2(int a){}
}
void main()
{
auto Foo = new foo;
Foo.method2(0);
}
outputs:
myfile.d(xx): Error: foo interface function 'void method1(int a)'
is not implemented
It seems that the compiler doesnt get that baz.method1 is actually bar.method1.
Note that the example illustrates that in baz, for some reasons, we know that method1 will always have the same implemtation. a baz implementer mays be down-casted as a bar (so making a dummy final method1 in bar is not possible).
Interfaces can only declare virtual members without implementation, or final members with implementation. Your code is attempting to override a virtual method with a non-virtual implementation. Due to the nature of interfaces, you cannot actually override anything within them. What you want instead is an abstract class.
abstract class baz: bar!int
{
override void method1(int a){}
}
Replacing your baz interface with the above class will clear up the issue.
As an example of why this isn't allowed, consider this code: (Does not compile, of course!)
interface Root {
int foo();
}
interface BranchA : Root {
override int foo() { return 1; }
}
interface BranchB : Root {
override int foo() { return 2; }
}
class C : BranchA, BranchB { }
What would (new C()).foo() return? The result is ambiguous. It is only acceptable to override the interface methods in a class, because unlike interfaces, you can only inherit one class at a time.
I am wrapping a C library using C++/CLI. The C library was designed to be used from an unmanaged C++ class. This means that the library functions accept a C++ object pointer and then provide that pointer back in callbacks. This enables the callback code to redirect requests to an appropriate event function in the calling C++ object.
The actual functions are quite involved, so I have simplified the problem space to just a few basic items:
// C library function signature
void CLibFunc(CLIBCALLBACK *callback, void *caller);
// C callback signature
// Second parameter is meant to point to the calling C++ object
typedef int (__stdcall CLIBCALLBACK) (int param1, void *caller);
// C callback implementation
int CallBackImpl(int param1, void* caller)
{
// Need to call the ManagedCaller's EventFunction from here
// ???
}
// C++/CLI caller class
public ref class ManagedCaller
{
public:
void CallerFunction(void)
{
// Call the C library function
// Need to pass some kind of this class pointer that refers to this object
CLibFunc(CallBackImpl, ????);
}
void EventFunction(param1)
{
}
}
Now the C library functions need to be called from a managed C++ class. Under C++/CLI, the garbage collector moves objects around in memory, so passing a simple fixed pointer to the class does not work anymore. I can solve the problem by pinning the object, but that is not recommended because it leads to memory fragmentation. It seems that another option would be to use auto_gcroot pointers, but I am fairly new to managed C++ an I am not sure how to make this work.
Does anyone know how to make this work? What kind of pointer should be passed to the C function? How should the callback implementation redirect to the calling object's event function?
This just happens to be similar to something I'm in the middle of working on right now.
Here is an blog post on providing native callbacks using C++ classes: http://blogs.microsoft.co.il/blogs/alon/archive/2007/05/29/Native-Callback.aspx
I'm not familiar with calling C++ member functions from C, but I have done an interface (abstract base) class to another C++ class for callbacks (similar to the article). Here is a basic example of what I am providing a bridge for:
// Interface (abstract base) class providing the callback
class IProvider {
public:
virtual ~IProvider() {}
virtual void Callback() = 0;
};
// User class of the callback
class CUser {
IProvider * m_pProvider;
public:
CUser(IProvider * pProvider) {
m_pProvider = pProvider;
}
void DoSomething() {
m_pProvider->Callback();
}
};
// Implementation of the interface class
class CHelloWorldProvider : public IProvider {
void Callback() {
printf("Hello World!");
}
};
// Usage of the callback provider in a pure native setting
void PureNativeUsage() {
CHelloWorldProvider oProvider;
CUser oUser(&oProvider);
oUser.DoSomething();
}
Now in order to make this available for managed implementations of the provider, we have to create a series of classes that provide the bridge.
// Where gcroot is defined
#include <vcclr.h>
// Managed provider interface class
public interface class IManagedProvider {
void Callback();
};
// Native bridge class that can be passed to the user
class CProviderBridge : public IProvider {
// Give the managed class full access
friend ref class ManagedProviderBase;
// Store a reference to the managed object for callback redirects
gcroot<IManagedProvider ^> m_rManaged;
public:
void Callback(){
m_rManaged->Callback();
}
};
// Managed provider base class, this provides a managed base class for extending
public ref class ManagedProviderBase abstract : public IManagedProvider {
// Pointer to the native bridge object
CProviderBridge * m_pNative;
protected:
ManagedProviderBase() {
// Create the native bridge object and set the managed reference
m_pNative = new CProviderBridge();
m_pNative->m_rManaged = this;
}
public:
~ManagedProviderBase() {
delete m_pNative;
}
// Returns a pointer to the native provider object
IProvider * GetProvider() {
return m_pNative;
}
// Makes the deriving class implement the function
virtual void Callback() = 0;
};
// Pure managed provider implementation (this could also be declared in another library and/or in C#/VB.net)
public ref class ManagedHelloWorldProvider : public ManagedProviderBase {
public:
virtual void Callback() override {
Console::Write("Hello World");
}
};
// Usage of the managed provider from the native user
void MixedUsage() {
ManagedHelloWorldProvider ^ rManagedProvider = gcnew ManagedHelloWorldProvider;
CUser oUser(rManagedProvider->GetProvider());
oUser.DoSomething();
}
Edit: Added code to show w/o the managed interface class example I use.
Here is a modified version of my example that can be used given your CLibFunc above. This is assuming how the C function performs the callback is accurate.
Also this might be able to be slimmed down a bit depending on how involved your callback classes are and how much freedom for extension you need.
// Where gcroot is defined
#include <vcclr.h>
// C callback signature
// Second parameter is meant to point to the calling C++ object
typedef int (__stdcall CLIBCALLBACK) (int param1, void *caller);
// C library function
void CLibFunc(CLIBCALLBACK *callback, void *caller) {
// Do some work
(*callback)(1234, caller);
// Do more work
}
// Managed caller interface class
public interface class IManagedCaller {
void EventFunction(int param1);
};
// C++ native bridge struct
struct CCallerBridge {
// Give the managed class full access
friend ref class ManagedCaller;
// Store a reference to the managed object for callback redirects
gcroot<IManagedCaller ^> m_rManaged;
public:
// Cast the caller to the native bridge and call managed event function
// Note: This must be __stdcall to prevent function call stack corruption
static int __stdcall CallBackImpl(int param1, void * caller) {
CCallerBridge * pCaller = (CCallerBridge *) caller;
pCaller->m_rManaged->EventFunction(param1);
return 0;
}
};
// C++/CLI caller class
public ref class ManagedCaller : public IManagedCaller {
// Pointer to the native bridge object
CCallerBridge * m_pNative;
public:
ManagedCaller() {
// Create the native bridge object and set the managed reference
m_pNative = new CCallerBridge();
m_pNative->m_rManaged = this;
}
~ManagedCaller() {
delete m_pNative;
}
// Calls the C library function
void CallerFunction() {
CLibFunc(CCallerBridge::CallBackImpl, m_pNative);
}
// Managed callback function
virtual void EventFunction(int param1) {
Console::WriteLine(param1);
}
};
// Usage
int main(array<System::String ^> ^args) {
ManagedCaller ^ oCaller = gcnew ManagedCaller();
oCaller->CallerFunction();
return 0;
}
Example A:
// pseudo code
interface IFoo {
void bar();
}
class FooPlatformA : IFoo {
void bar() { /* ... */ }
}
class FooPlatformB : IFoo {
void bar() { /* ... */ }
}
class Foo : IFoo {
IFoo m_foo;
public Foo() {
if (detectPlatformA()} {
m_foo = new FooPlatformA();
} else {
m_foo = new FooPlatformB();
}
}
// wrapper function - downside is we'd have to create one
// of these for each function, which doesn't seem right.
void bar() {
m_foo.bar();
}
}
Main() {
Foo foo = new Foo();
foo.bar();
}
Example B:
// pseudo code
interface IFoo {
void bar();
}
class FooPlatformA : IFoo {
void bar() { /* ... */ }
}
class FooPlatformB : IFoo {
void bar() { /* ... */ }
}
class FooFactory {
IFoo newFoo() {
if (detectPlatformA()} {
return new FooPlatformA();
} else {
return new FooPlatformB();
}
}
}
Main() {
FooFactory factory = new FooFactory();
IFoo foo = factory.newFoo();
foo.bar();
}
Which is the better option, example A, B, neither, or "it depends"?
I would say that your explicit factory option (option B) is generally better.
In your first example your Foo class is effectively doing two jobs, it's a factory and it's a proxy. Two jobs, one class, makes me uneasy.
Your second option puts a little more responsibility on the client: they need to know to use the factory, but this is such a widely used idiom that I think it's not hard to understand.
The problem with A is that you have to implement every method of IFoo in Foo. That is not a big deal if there are only a couple, but is a pain if there are dozens of them. If you are working with a language that supports factory methods, such as Curl, then you could put a factory method in IFoo:
{define-class abstract IFoo
{method abstract {bar}:void}
{factory {default}:{this-class}
{if platformA? then
{return {FooPlatformA}}
else
{return {FooPlatformB}}
}
}
}
{define-class FooPlatformA {inherits IFoo}
{method {bar}:void}
}
...
def foo = {IFoo}
{foo.bar}
If you ask me B is way better - since Foo itself does not need to do any switching on platform. Why does that matter? Well, since you probably want to test all components separately - Foo with a 'test' IFoo, FooPlatformA separately on platform A and FooPlatformB on platform B. If you stick the choice inside Foo you need to test Foo on both A and B, not only the different IFoos. Makes the components more coupled for no apparent reason.
The factory is a cleaner solution as you do not have implement each member of the interface in the wrapper class Foo : IFoo. Imagine, each time you modify the IFoo interface you would need update the wrapper. When programming, depending on your goals, try to consider maintainability as much as possible.
Are all 'platforms' available or only one of them? Is the only difference between the platforms is logic? Thinking from a game developer perspective I would use #defines to implement this.
class Platform : IPlatform
{
void Update()
{
#if PLATFORM_A
* ... Logic for platform A */
#elif PLATFORM_B
* ... Logic for platform A */
#endif
}
}
HTH,
Interfaces are used when it is possible that multiple implementations of a single functional set may exist. This sounds as though it applies to your particular scenario.
In terms of your examples, I would definitely roll with B, it is easier to maintain. A embeds too much common logic [ie platform detection] within individual classes [and/or methods]. If you are to build your own Factory class, try to generalize it [through a generic Resolve<IType> () method or something], as opposed to a method\class per interface.
For instance,
// i called it a "container" because it "contains" implementations
// or instantiation methods for requested types - but it *is* a
// factory.
public class Container
{
// "resolves" correct implementation for a requested type.
public IType Resolve<IType> ()
{
IType typed = default (IType);
if (isPlatformA)
{
// switch or function map on IType for correct
// platform A implementation
}
else if (isPlatformB)
{
// switch or function map on IType for correct
// platform B implementation
}
else
{
// throw NotSupportedException
}
return typed;
}
}
However, rather than implement your own Factory pattern, you may wish to investigate alternative implementations, such as MS's Unity2.0 or Castle Windsor's CastleWindsorContainer. These are easy to configure and consume.
Ideally,
// use an interface to isolate *your* code from actual
// implementation, which could change depending on your needs,
// for instance if you "roll your own" or switch between Unity,
// Castle Windsor, or some other vendor
public interface IContainer
{
IType Resolve<IType> ();
}
// custom "roll your own" container, similar to above,
public class Container : IContainer { }
// delegates to an instance of a Unity container,
public class UnityContainer : IContainer { }
// delegates to an instance of a CastleWindsorContainer,
public class CastleWindsorContainer : IContainer { }
Oh, suppose I ought to shout out to Ninject and StructureMap too. I am just not as familiar with these as with Unity or CastleWindsor.