Is there C++ equivalent of Objective-C Instance and Class Methods? - c++

I am learning C++ with Xcode (cocos2d-x).
A regular c++ void method I think is equivalent to an obj-c -void Instance method.
Is there is a c++ equivalent of the obj-c +void Class method?
Thanks

There is no direct equivalent to class methods in C++; however, in many cases C++ static methods can be used in place of class methods.
For example, this Objective-C code:
#interface MyClass : NSObject
{
int _number;
}
+ (MyClass*)newInstance;
- (void)instanceMethod;
#end
#implementation MyClass
+ (MyClass*)newInstance
{
return [[self alloc] init];
}
- (void)instanceMethod
{
_number = 123;
std::cout << _number;
}
#end
int main(void)
{
MyClass* foo = [MyClass newInstance];
[foo instanceMethod];
return 0;
}
is roughly equivalent to this C++ code:
class MyClass
{
int _number;
public:
static MyClass* newInstance();
void instanceMethod();
};
MyClass* MyClass::newInstance()
{
return new MyClass();
}
void MyClass::instanceMethod()
{
_number = 123;
std::cout << _number;
}
int main(void)
{
MyClass* foo = MyClass::newInstance();
foo->instanceMethod();
return 0;
}
That example also illustrates one of the differences between class methods and static methods.
+newInstance will be inherited by subclasses and will always work correctly (it will always return an instance of a subclass). It can also be overridden by a subclass.
Static methods like MyClass::newInstance() cannot be inherited or overridden. It will always return an instance of MyClass.
So when you're porting code between Objective-C and C++ there are cases when you cannot use static methods in place of class methods. But for most cases, C++ static methods are a fine replacement.

class SomeClass {
public:
static void someMethod();
};

The equivalent of class methods in C++ would be static functions.
static return_type function_name(parameters);
Just like in Objective-C, in static functions you cannot reference instance variables (since there's no instance), only static variables.

For example.
class A{
public:
static void doIt();
};
Then you can call function doIt with:
void main()
{
A::doIt();
}

Objective-C has implicit metaclasses as explored in "What is a meta-class in Objective-C?" article. The full power of metaclasses is not unleashed, however. It would require multiple inheritance support and other technical decisions, as described in famous "Putting Metaclasses to Work" book. That was probably too complex for Objective-C authors, so they decided to hide metaclasses in Objective-C.
Objective-C targets Objective-C runtime (obj.dll or libobjc.dylib), and there were C++ compilers (DTS C++, Direct-to-SOM C++) targetting SOM the same way. This makes DTS C++ closer to Objective-C than C++ in its design. I managed to get old Windows DTS C++ compiler running on Windows 8 this way:
Download VAC 3.5 fixpak 9 from IBM FTP. This fixpak contain many files, so you don't even need to full compiler (I have 3.5.7 distro, but fixpak 9 was big enough to do some tests).
Unpack to e. g. C:\home\OCTAGRAM\DTS
Start command line and run subsequent commands there
Run: set SOMBASE=C:\home\OCTAGRAM\DTS\ibmcppw
Run: C:\home\OCTAGRAM\DTS\ibmcppw\bin\SOMENV.BAT
Run: cd C:\home\OCTAGRAM\DTS\ibmcppw\samples\compiler\dts
Run: nmake clean
Run: nmake
hhmain.exe and its dll are in different directories, so we must make them find each other somehow; since I was doing several experiments, I executed "set PATH=%PATH%;C:\home\OCTAGRAM\DTS\ibmcppw\samples\compiler\dts\xhmain\dtsdll" once, but you can just copy dll near to hhmain.exe
Run: hhmain.exe
I've got an output this way:
Local anInfo->x = 5
Local anInfo->_get_x() = 5
Local anInfo->y = A
Local anInfo->_get_y() = B
{An instance of class info at address 0092E318
}
This example does not use metaclasses, it's just for checking DTS C++ compiler.
Metaclasses in SOM are explicit, thus so called "class methods" are no more than "instance methods" of metaclass. Each object belongs to some class, managed by so called class-object created in runtime. Class-object is itself an instance of another class, named metaclass. Developer of a class can specify metaclass constraint via IDL or DTS C++ pragma.
If one needs to call method of known at compile time class, one can just reference class-object and invoke its method just like ordinary object which class-object is in essence. Class-object is being referenced via DLL import/export mechanisms, similar to Objective-C.
If one needs to invoke a method of a class that object is belonging to, one needs to invoke somGetClass() to get class-object, typecast it to metaclass type and invoke desired method. In DTS C++ one should probably not need to do redundant typecasting, but I am not expert in IBM DTS C++ properties.

Related

Is there any way to convert a superclass pointer to subclass pointer by subclass name in c++ string?

Recently, I'm working on something like reflection in c++ using by my plugin system. Right now, I wonder if I can convert a super-class pointer into sub-class pointer given the string name of sub-class:
class SuperClass
{
public:
SuperClass(const string &name):class_name(name){}
// a convert function like
// return value should variant like SubClassA * or SubClassB *
// SubClassA * ConvertByName();
private:
string class_name;
};
class SubClassA: public SuperClass
{
public:
SubClassA():SuperClass("SubClassA")
};
class SubClassB: public SuperClass
{
public:
SubClassB():SuperClass("SubClassB")
}
when using:
// some place create instance
SuperClass *one = new SubClassAï¼›
SuperClass *two = new SubClassB;
// other place using
auto a = one->ConvertByName(); // a is of type SubClassA
auto b = two->ConvertByName(); // b is of type SubClassB
Can it be realized? Or is there any better way in c++?
[Update 1]
There my be some other sub-classes, such as, SubClassC, SubClassD, ...
So basically, we don't know what and how many sub-classes are derived from this SuperClass. What we know about sub-class is only its class name in string format.
[Update 2]
My motivation
I need this for plugin system. I want to create a plugin anytime, but don't want hack into my plugin core system codes. That is plugin codes are isolated from projects. A plugin system will never know what and how many plugins are added into system until runtime
Possible, well, this way you manually somewhat reimplement dynamic dispatch and make your class a kind of sealed.
struct Base {
Base(std::string type_id): type_id(std::move(type_id)) {}
template<class F> auto visitThis(F &&f) const;
template<class F> auto visitThis(F &&f);
private:
std::string type_id;
};
struct Child1: Base { Child1(): Base("Child1") {}};
struct Child2: Base { Child2(): Base("Child2") {}};
template<class F> auto Base::visitThis(F &&f) const {
if(type_id == "Child1") {
return std::invoke(std::forward<F>(f),
static_cast<Child1 const *>(this));
}
else if(type_id == "Child2") {
return std::invoke(std::forward<F>(f),
static_cast<Child2 const *>(this));
}
else throw std::runtime_error("Unsupported subclass");
}
template<class F> auto Base::visitThis(F &&f) {
if(type_id == "Child1") {
return std::invoke(std::forward<F>(f), static_cast<Child1 *>(this));
}
else if(type_id == "Child2") {
return std::invoke(std::forward<F>(f), static_cast<Child2 *>(this));
}
else throw std::runtime_error("Unsupported subclass");
}
int main() {
std::unique_ptr<Base> b1 = std::make_unique<Child1>();
b1->visitThis([](Child1 const *ch) { std::cout << "Hi, Ch1!\n"; });
}
If your classes all have some virtual thing, consider using dynamic_cast
See this C++ reference for details, and read a good C++ programming book.
Read also the documentation of your C++ compiler (e.g. GCC)
Right now, I wonder if I can convert a super-class pointer into sub-class pointer given the string name of sub-class
This is not possible without specific coding and programming conventions
(since the class names do not exist at runtime). Look inside Qt or RefPerSys as an example.
A possible approach could be to write your C++ code generator to help you (so generate parts of your C++ code - probably some header file containing your class declarations-, like Qt does with its moc, and configure your build automation tool, e.g. your Makefile). Look perhaps inside ANTLR, SWIG, GPP, etc...
A more ambitious approach, if you use GCC, would be to write your own GCC plugin. Consider also extending Clang. This is worthwhile only for large existing code bases.
A plugin system will never know what and how many plugins are added into system until runtime
It seems that you are designing some plugin machinery. Take inspiration from Qt plugins or FLTK plugins. If on Linux, see manydl.c and consider generating some of the C++ code of your plugins (see e.g. this draft report, and the CHARIOT and DECODER European projects).
BTW, do you want to unload plugins (on Linux, call dlclose(3); read also then the C++ dlopen minihowto)? Do you have a multi-threaded application? If you do, you'll better have some locking (e.g. std::mutex) to avoid parallel plugin loading.
You could also consider generating at runtime some glue code: e.g. using libgccjit or asmjit, or simply generating some temporary C++ code (e.g. on Linux in /tmp/generated.cc that you would compile - maybe with popen(3) - using g++ -Wall -O -fPIC /tmp/generated.cc -o /tmp/generated-plugin.so) and later dlopen(3) that /tmp/generated-plugin.so. Read Drepper's paper how to write shared libraries (for Linux).
C++ does not ship enough information in binaries to write new code.
Dynamically linked C++ code do not carry enough information for other dynamically linked code to build a copy of the class at link time.
So there is no way, short of shipping a C++ compiler, to do exactly what you are asking. I have heard of some people who go that far, and embed C++ compilers into their hand-grown "dynamic linking" environment, but usually by that point you are better off with using a language where that is a built-in feature, or not using the raw C++ object model and using something reflection-enabled.
It is quite likely that the underlying problem you are trying to solve using this technique can be solved in C++, if one exists.

Generic Objective-to-C++ translation strategy

I'd like to expose ObjC notification handlers to my C++ client code.
I'm doing it this way.
I wrapped an ObjC object (call it X) inside a C++ object.
X observes the notification and registers a callback (call it F).
F translates the ObjC structures from the notification into their C++ counterparts, calls a user-registered global C++ callback function (call it FF). The translated C++ structs become the input arguments of FF.
Now the problem is that the arguments' original ObjC structures are complex, containing multiple layers of ObjC objects that need to be translated.
On my side, the wrapper observer F needs to do nothing special, just calling the client's FF.
What is the more proper strategy of my translation at this point?
Should I:
Translate those structures down to the bottom-level of all their members so that I have equivalent C++ structures to use as the arguments, or,
Create a C++ class to wrap these arguments into one object and expose the class interface to user so they can use those C++-wrapped arguments in their C++ implementation, or,
Give up on the wrapping idea and ask user to code in ObjC and register their own observer functions directly?
My targeted users are iOS developers that may or may not be Android developers too.
You can mix c++ and objective-c++ in a .mm implementation file. This means you can give a c++ lambda (or block) to the objective-c++ class that references your c++ owner.
something like this:
implementation.mm:
#interface Shim : NSObject
{
std::function<void>() _notify;
}
#end
#implementation Shim
- void register_cpp(std::function<void>() f)
{
_notify = std::move(f);
}
- (void) my_handler()
{
if(_notify)
_notify();
}
#end
struct cpp_class::impl {
impl()
: _shim([Shim alloc[init]])
{
_shim.register_cpp(std::bind(&impl::callback, this));
}
private:
void callback() {
// do callback here;
}
Shim* _shim;
};
cpp_class::cpp_class()
: _impl(new impl)
{
}
cpp_class::~cpp_class()
{
delete _impl;
}
header.h:
struct cpp_class{
cpp_class();
~cpp_class();
private:
struct impl;
impl* _impl;
};
In reality you'll want to be careful to ensure that objects still exist when doing callbacks (argues for weak_ptr::lock(), enable_shared_from_this, etc.) since objective-c likes to put callbacks onto a thread's run loop (basically a queue) and that means your c++ object can go away before the callback arrives - but this code should give you the right idea.

porting C++ library to .NET

I have this simple library written in C++ (source code included)
struct MyStruct
{
char message[ 90 ];
int t;
};
enum MyEnum
{
MY_ENUM_1, MY_ENUM_2
};
class IEvent
{
public:
virtual ~IEvent() {}
virtual void event1( time_t ) = 0;
virtual void event2( MyStruct s ) = 0;
virtual void event3( MyEnum e ) = 0;
};
class Impl;
class MY_API Controller
{
public:
Controller( IEvent* eventListener );
~Controller();
void addListener( IEvent* eventListener );
void removeListener( IEvent* eventListener );
void f1( MyEnum e );
void f2();
private:
Impl* mImpl;
};
The code is implemented in C++11. I need to port this code to .NET.
I thought that a good choice can be C++/CLI but after lots of google I didn't find nothing.
Does someone know how to port this code in C++/CLI? I am able to build all the library in C++/CLI but the library doesn't export any symbols.
Edit1
The library is huge and a re-write in other language is too expensive.
If you want to port this code to .NET, to be used in other .NET languages, such as C#, then you're going to want to re-work how this library does things. Regardless of what language you choose to implement in, if your goal is to be consumed by other .NET languages, you should switch to the .NET paradigms.
For example: currently, you have an abstract class named IEvent. You could create a .NET interface named IEvent, and implement it the same way, but that's not how you do things in .NET. Instead, you'd want to define 3 delegate types, and have your Controller class define 3 events of those delegate types. Instead of addListener and removeListener, each of the events would have add and remove methods (accessed through += and -=).
delegate void Event1Handler(object sender, DateTime data);
delegate void Event2Handler(object sender, MyStruct data);
delegate void Event3Handler(object sender, MyEnum data);
public class EventExample_Controller
{
public event Event1Handler Event1;
public event Event2Handler Event2;
public event Event3Handler Event3;
}
As for the language to use, my initial response would be "C# if you can, C++/CLI if you have to". You haven't said what this library does, it may not be easy, or even possible, to do it in C#. But if you can do it in C#, then you'll get the benefits that language provides: Many of the benefits have equivalents in C++/CLI (e.g., linq query syntax can be represented with regular syntax, extension methods can be called as regular static methods, everything using the async keyword can be done with Tasks and a crapload of state variables), but some are C# only (e.g., having one assembly that works in 32-bit and 64-bit mode).
As for your try to compile the library as-is in C++/CLI, you need to mark the classes as managed classes. Change the classes to public ref class, and the enums to public enum class, and that'll create them as managed. Your next step will be to switch all your pointers to your own classes from unmanaged pointers (*) to managed references (^), and use gcnew instead of new for them.

How a member func can know *programmatically* the 'name of the object' that is calling it?

Let say we have a class MyClass that has and a memberfunc().
An object is created for this MyClass, say ObjA.
i.e MyClass ObjA;
ObjA calls memberfunc().
Can we get this name 'ObjA' inside memberfunc() programatically?
Note: I know how to get the type of the object, i.e 'MyClass', using RTTI (Run-Time Type Identification), the same is also explained by radman below.
EDIT:
If this is NOT POSSIBLE in c++, Is it possible in any other programming language?
EDIT2
Made some modification to the question as few were unable to interpret.
There are several issues here:
Objects don't call anything, code does.
Objects don't have a name. An object is usually assigned to a variable, often to more than one variable, often to no variable at all, such as an array element.
Getting access to the call stack might give you some idea of the calling class that owns the code that called you, but even this usually requires a level of introspection that goes beyond the reflection facilities of most languages.
Python is a notable exception. It can give you the stack to walk and figure out lots of interesting things. C++ won't.
I have seen C++ libraries that crack open the stack (this is very non-portable, by the way) and thus give code the ability to figure stuff out like, "Who called me?" but I haven't used that stuff for years.
No, there is no way for it. C++ has no reflection, which would might make this possible. On 2nd thought, even the reflection facilities of e.g. Java don't have this feature.
C++ is compiled directly to machine code, which does not contain any identifiers from the source code anymore. You could of course store the "variable name" in a member field (provided the object is referred to under a single name...).
No, the object name is something that only exists in your source code. Once compiled, the object reference is just a memory offset. If you want to know the variable name, you have to have a string somewhere describing it.
The facility to get a variable name in languages with introspection mechanisms (such as Reflection) is pretty limited and not at all widely available. Even in C# - the girly man language - to get a variable name you need to use a quirky C# 3.5 feature called projection and then jump through hoops to extract it. Even then, you have to program for it - it won't just be available at any point of the code.
After some thinking the question you are posing - getting the objects' name from a member function - is theoretically impossible. Consider this scenario:
class ObjA {
public:
void memberfunc() {
//confused??? instance1 or instance2?
}
};
//main
ObjA instance1;
ObjA* instance2 = &instance1;
instance2->memberfunc();
In the above example we have one instance of ObjA with two variables pointing to it(and I use term pointing rather loosely here). Those variables are something completely outside of any conceivable control of the object, hence it's impossible to get at them, even if the facility to get a variable name is available.
In C# you can use anonymous classes and Reflection to get a variable name. The method of doing so is quite awkward and if you are trying to use this to demonstrate something to someone, give up now, because you will both be confused. The technique uses some features that are new to mainstream programming and include anonymous classes, projection, extension methods and Reflection.
public static class Extensions {
public static string GetFirstPropertyName(this object obj) {
return obj.GetType().GetProperties()[0].Name;
}
}
public class Program {
public static void Main() {
int intVal = 5;
var name = (new {intVal}).GetFirstPropertyName();
//name=="intVal"
}
}
Well your question seems a little bit unclear but assuming that you want to print out the name of the class in one of it's member functions it is quite possible.
What you need to use is the typeid command. This extracts a close to human readable name for a an object of class type at runtime. However you can't rely on this name being consistent across platforms i.e. the name you get may vary from platform to platform (what I got from the example code below was '4ObjA'.
#include <iostream>
#include <typeinfo>
class ObjA
{
public:
void memberfunc()
{
std::cout << typeid(*this).name() << std::endl;
}
};
int main(int argc, char **argv)
{
ObjA obj;
obj.memberfunc();
}
Your question isn't entirely clear - do you want to know the object the method belongs to? Or the name of the method calling the member-function? Oo something else..?
In most object-oriented languages, you can get the name of the currently class quite easily:
class Myclass(object):
def memberfunc(self):
print self.__class__.__name__
obja = Myclass()
obja.memberfunc() # prints Myclass
You can't sensibly get the obja identifier as a name (in almost any language), and I can't see why you would want to (in cases like this, you'd use some kind of key/value mapping)
If you want to get the name of the method that called the method, you would have to inspect the call stack, e.g in Python using the inspect method:
import inspect
class Myclass(object):
def memberfunc(self):
current_call = inspect.stack()[0]
previous = inspect.stack()[1]
print previous[3]
def somefunc():
obja = Myclass()
obja.memberfunc() # prints somefunc
somefunc()
I imagine this isn't as easy in other languages
Again, the cases where you would want to do such a thing are rare, usually limited to introspection-heavy things like code coverage tools and debuggers
As has been covered in other posts, there is no direct way to access the variable name identifier that you choose in code at runtime - there is simply no need for it from the machine perspective. However, in Ruby it is trivial to get at the details of the caller in terms of its structure:
class Foo
def foo
puts self.class
end
end
class Bar < Foo
end
f = Foo.new
b = Bar.new
f.foo #=> Foo
b.foo #=> Bar
You can do similar in C++ with typeid, but it is not exact. For instance:
#include <iostream>
class Foo {
public:
void foo () { std::cout << typeid(this).name() << std::endl; }
};
int main () {
Foo f;
f.foo (); // on my system returns P3Foo
return 0;
}
This is sort of a hack, but you could use Macros to store the class identifier name. Here's what I mean:
#include <iostream>
#include <string>
#define createMyClass(x) MyClass x("x")
class MyClass{
string _name;
MyClass( const string& name ) : _name(name){}
memberfunc(){
std::cout << "Name: " << _name << std::endl;
}
}
int main (int argc, char **argv) {
createMyClass( ObjA );
ObjA.memberfunc(); // prints the name
return 0;
}

Passing a C++ method to an Objective-C method

I have a C++ class 'Expression' with a method I'd like to use in my Objective-C class 'GraphVC'.
class Expression {
double evaluate(double);
}
And my Objective-C class:
#implementation GraphVC : UIViewController {
- (void)plot:(double(*)(double))f;
#end
I thought that it would be easiest to pass around function pointers that take a double and return a double, as opposed to C++ objects, but I haven't had much success using functional.h. What's the best way to use my C++ method from Objective-C?
EDIT: Thanks for your quick responses. Allow me to elaborate a bit... I have a backend written in C++ where I manipulate objects of type Expression. There's subclasses for rational, polynomial, monomial, etc. My initial idea was to use mem_fun from , but I wasn't able to get code compiling this way. I also had trouble using bind1st to bind the this pointer.
Writing an Objective-C wrapper is a possibility, but I'd rather use the already existing evaluate() function, and I don't want to break the clean separation between the backend and the iPhone GUI classes.
I can't have a global expression or use a static method (I need to plot arbitrary Expression instances.
I should have more explicitly stated that I need to pass a C++ member function (not a static function or existing C function) to an Objective-C object. Has anyone had luck using C++'s <functional> to turn member functions into pointers I can use in an Objective-C object, or should I use an Objective-C wrapper?
If you want to make a pointer to a method in C++, you need to include the class name, like this:
class Foo
{
public:
double bar(double d)
{
return d;
}
};
void call_using_obj_and_method(Foo *f, double (Foo::*m)(double d))
{
(f->*m)(3.0);
}
int main()
{
Foo f;
call_using_obj_and_method(&f, &Foo::bar);
return 0;
}
Note that you need an instance of the class as well. In my example this is another parameter, though you could let it be a global variable, or a singleton instance of class Foo.
Though, like jkp said, you can also solve the problem by making the method static or turning it into a regular function.
EDIT: I'm not sure if I understand your question correctly. I don't think you need to use functional. Here is how my example would look in Objective-C++:
#include <Cocoa/Cocoa.h>
class Foo
{
public:
double bar(double d)
{
return d;
}
};
typedef double (Foo::*fooMethodPtr)(double d);
#interface Baz : NSObject
{
}
- (void)callFooObj:(Foo *)f method:(fooMethodPtr)m;
#end
#implementation Baz
- (void)callFooObj:(Foo *)f method:(fooMethodPtr)m
{
(f->*m)(3.0);
}
#end
int main()
{
Foo f;
Baz *b = [[Baz alloc] init];
[b callFooObj:&f method:&Foo::bar];
return 0;
}
I would suggest wrapping the C++ class in an Objective-C class, and then also providing a
- (void) plotWithObject:(id)obj
{
double result = [obj evaluate: 1.5];
// ... etc ...
}
in addition to the plot: method.
I think the problem here is that you are trying to pass a member function of your Expression class to the Objective-C class. This will not work because it's expecting a this pointer as the first argument to that function (therefore the signature is not the same as the one expected by the plot: method.
If you make the C++ method a static, you can do this, but then you don't buy yourself a lot over using a standard C function.
IE, if the Expression class looked like this:
class Expression {
static double evaluate(double);
}
You should be able to call it like this:
[self plot:myExpression.evaluate(&Express::evalulate)];
As I say though, there isn't a huge amount of value in this because you may as well be using a standard C function (unless you can do something in the C++ class that is more useful to you).
I did once look at trying to bridge boost::bind() results with objective-c methods but didn't get very far. I'm sure if you dig deep enough in the C++ runtime you could do it though.
If your C++ member function returns a double, can't your code just look like this?
- (void)plot:(double)f;
...
[self plot:myExpression.evaluate(aDouble)];
Or something similar. I've not used much mixing of Obj-C and C++, but this is how I would approach it. You also might have to have a .mm extension on your Objective-C++ file if you're mixing them like that.
Why wouldn't you pass the instantiated c++ class around inside an NSValue and then call the c++ method directly?
- (NSValue*)getExpression
{
Expression* e = new Expression();
return [[NSValue alloc] initWithPointer:e];
}
- (void)callExpression(NSValue*)expression
{
Expression* e = [expression pointerValue];
e->evaluate();
}