I have another odd problem with Objective C inheritance. I have a protocol called IGameObject, a class GameObject that inherits from NSObject and IGameObject and finally a Player that inherits from GameObject..
The problem is that when I assign a Player* to a IGameObject*, this produces an error, but it works ok when I assign a Player* to a GameObject*. I haven't seen that this is not possible in all I have read. Here the code:
-(IGameObject*) clone
{
Player* p=(Player*) 0xFFfFFFFF;
//Throws an error saying that Cannont initialise a variable of type IGameObject with an value of Player*
IGameObject* go=p;
//This works perfectly
GameObject* go2=p;
return [[Player alloc] initWithGameObject:self];
}
Could anybody guess what is happening?
Thanks in advance.
When returning (or declaring) a type that is only known by its interface, don't treat it as an object pointer. Instead, use:
-(id<IGameObject>) clone {
And:
id<IGameObject> go=p;
This should clear up that warning.
Sidenote: Why in the world are you assigning p to a memory address?!
You cannot create a pointer to a protocol
IGameObject* go=p;
is meaningless.
Related
Hi this is my first time making a question so hopefully i have done this right :)
In my code Im trying to make a Arraylist that is within a class that only holds floats so I made this: (some information is taken away to make it easier to read)
class object {
private ArrayList yc=new ArrayList<Float>();
private ArrayList xc=new ArrayList<Float>();
object(float xer,float yer,float rer){
xc.add(10.0);
x=xer;
y=yer;
r=rer;
}
void update(){
print(xc.get(0))
x=xc.get(0);
}
}
everything else except x=xc.get(0) works outside of the class this assignment works but inside the class it doesn't
hope this makes sense thanks.
It seems like when you initialised the variable xc you specified the type of the ArrayList to Float. However, when declaring xc, you did not specify the type.
When you try to assign variable x with xc.get(0), you are basically assigning any Object to variable x that was declared as a Float.
To solve this issue you can declare your variable xc specifying the type of the ArrayList: private ArrayList<Float> xc = new ArrayList<Float>();
Also, processing offers the helper class FloatList as well if this suits your program.
This should solve your issue, depending on the rest of your code.
I'm currently testing some simple AngelScript stuff, and noticed something I find a bit strange when it comes to how objects are initialized from classes.
Let's say I define a class like this:
class MyClass {
int i;
MyClass(int i) {
this.i = i;
}
}
I can create an object of this class by doing this:
MyClass obj = MyClass(5);
However it seems I can also create an object by doing this:
MyClass obj;
The problem here is that obj.i becomes a default value as it is undefined.
Additionally, adding a default constructor to my class and a print function call in each one reveals that when I do MyClass obj = MyClass(5); BOTH constructors are called, not just the one with the matching parameter. This seems risky to me, as it could initialize a lot of properties unnecessarily for this "ghost" instance.
I can avoid this double-initialization by using a handle, but this seems more like a work-around rather than a solution:
MyClass# obj = MyClass(5);
So my question sums up to:
Can I require a specific constructor to be called?
Can I prevent a default constructor from running?
What's the proper way to deal with required parameters when creating objects?
Mind that this is purely in the AngelScript script language, completely separate from the C++ code of the host application. The host is from 2010 and is not open-source, and my knowledge of their implementation is very limited, so if the issue lies there, I can't change it.
In order to declare class and send the value you choose to constructor try:
MyClass obj(5);
To prevent using default constructor create it and use:
.
MyClass()
{
abort("Trying to create uninitialized object of type that require init parameters");
}
or
{
exit(1);
}
or
{
assert(1>2,"Trying to create uninitialized object of type that require init parameters");
}
or
{
engine.Exit();
}
in case that any of those is working in you environment.
declaring the constructor as private seems not to work in AS, unlike other languages.
following problem:
I want to build a function which returns me a Pointer to an derived object from an abstract class. I think, the memory is freed when the function is left because i get an alloc-error. But i can't give the object back, because the class is abstract. In the function i decide, which derived class the object will be have. How can I solve the problem?
Any idea?
QgsSymbolV2* QGISFunc::ReadClassSymbolsXML(QString FeatureType, QXmlStreamReader &reader)
{
QgsMarkerSymbolV2* p_mlmSymbol=0;
try
{
QgsLineSymbolV2 mllSymbol;
QgsFillSymbolV2 mlfSymbol;
QgsMarkerSymbolV2 mlmSymbol;
...
return &mlmSymbol; // alloc error
You are returning the address of a variable with automatic storage. That object gets destroyed when the function returns. The solution is to allocate the object on the heap. I suggest using a smart pointer (unique_ptr or shared_ptr in combination with make_shared<>()) for that purpose and return the smart pointer.
std::shared_ptr<QgsSymbolV2> QGISFunc::ReadClassSymbolsXML(
QString FeatureType,
QXmlStreamReader &reader
)
{
try
{
...
std::shared_ptr<QgsSymbolV2> spObj = make_shared<QgsMarkerSymbolV2>();
...
return spObj;
}
...
}
Your problem has nothing to do with the class being abstract. You create an object on the stack and then return its address. That address though will no longer be valid after the function returns. If you really want to return a pointer and delegate ownership to the caller, why not create it on the heap with new? Don't forget to delete it though later when you are done with that object, or consider smart pointers as #AndyProwl suggests.
I need to do some maintenance on an Objective-C application (updating it to use a new API), and having never used the language before, I'm a bit confused.
I have an Objective-C++ class which implements an interface from my API, and this is used within a block, however whenever it is accessed within the block, it fails with an access violation error (EXC_BAD_ACCESS).
Furthrer investigation shows that none of the constructors for the object in question are being called. It is declared within the containing scope, and uses the __block modifier.
To try and understand this, I made a quick scratch application, and found the same thing happens there:
class Foo
{
public:
Foo() : value(1) { printf("constructor"); }
void addOne() { ++value; printf("value is %d", value); }
private:
int value;
};
void Bar()
{
Foo foo1; // prints "constructor"
__block Foo foo2; // doesn't print anything
foo1.addOne(); //prints "2"
foo2.addOne(); //prints "1"
}
Can anyone explain what is happening here? Why isn't my default constructor being called, and how can I access the object if it hasn't been properly constructed?
As I understand it, your example there isn't using a block as such, but is declaring foo2 as to be used by a block.
This does funny things to the handling of foo2, which you can read more about here.
Hope that helps.
Stumbled upon this old question. This was a bug that's long been fixed. Now __block C++ objects are properly constructed. If referenced in a block and the block is copied, the heap copy is move-constructed from the original, or copy-constructed if it cannot be move-constructed.
I am having a really odd problem trying to set a simple float value to 1.
My property:
{
float direction;
}
#property(nonatomic)float direction;
Which is synthesized:
#synthesize direction;
I then used the following code:
- (void)setDirection:(float)_direction {
NSLog(#"Setter called with value of %f",_direction);
self->direction = _direction;
}
For testing purposes...
When I try to change the value with this,
[[w getCharacter] setDirection:1.0f];
where [w getCharacter] gives this:
return [[[self scene] gameLayer] player];
I get the warning, "setDirection not defined."
If I switch to dot notation([w getCharacter].direction), I get "confused by earlier errors, bailing out".
Here is where the weirdness starts. When I try to change the value, the debug message displays _direction = 0.00000. When I check the number later, its still 0.000. I am clearly trying to change it to 1, why is this not working?
The simplest explanation is that [w getCharacter] doesn't return the class of object you think it does. Only the class that has direction defined for it can respond to the message. You should test this by explicitly calling it with the class it defined for.
It is possible you did not include the header that defines the method.
Two probably unrelated issues:
The self->direction construction will work for a scalar value but it does an end run around the entire class concept. In this case just use: 'direction=_direction;` and it will set it directly.
Apple reserves all names that start with underscores for its own internal use. You should not use them because Objective-c has a global name space. It's possible that you can accidentally use an Apple variable that is defined deep within a framework. (This is why framework constants all start with NS,CF,CA etc.)
[Note: In the Comments, the author says to ignore this answer.
self.direction = 1; is syntactic sugar for
[self setDirection: 1];
when you call
-(void)setDirection:(float)_newDirection {
self.direction = _newDirection;
}
You seem to be telling the compiler or preprocessor to set up a recursive loop for you. The preprocessor (I think) changes it to this:
-(void)setDirection:(float)_newDirection {
[self setDirection: _newDirection];
}
If you call it simply
-(void)setDirection:(float)_newDirection {
direction = _newDirection;
}
the assignment should work (it worked for me just now)