|
I think you are missing an indirection level:
unit* LUnits = new unit[2];
Lunis is a normal array. Elements are unit objects
LUnits[0] = dynamic_cast<unit*>(S);
This fails because LUnits[0] is a unit , not a unit*
The first line should be:
unit** LUnits = new unit*[2];
Mircea
modified 23-Aug-24 13:45pm.
|
|
|
|
|
unit* LUnits = new units[2] creates an array of 2 unit , not an array of 2 pointers to unit.
You probably want a double dereference:
unit** LUnits = new units*[2]; soldier* S = new soldier;
unit[0] = S;
It feels like there should be a better way to do that.
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
modified 23-Aug-24 13:54pm.
|
|
|
|
|
Thank you guys indirection was the problem
modified 23-Aug-24 16:56pm.
|
|
|
|
|
I am adding a new object to an existing object.
In QtCreator, I have an option to add it /pass it as a class new parameter.
The other option is to add new object as a .so library.
I am asking for (academic) evaluation / discussion of each option,
as a C++ task , nothing to do with Qt.
I will appreciate your time , however, off subject ,
immature flaming responses will be as always ignored.
Cheers
|
|
|
|
|
Sorry, I must be hard of thinking, but your question doesn't make much sense to me. By "adding an object to a class" I think in terms of
class C1 {
int i;
double d;
public:
C1(int x, double y) : i(x), d(y) {}
...
};
class C2 {
int i;
double d;
std::string str; public:
C2(int x, double y, std::string s) : i(x), d(y), str(s){}
...
};
If that's the case, then you've got a couple of choices. If you've got full control of the source, including the definition and implementation of the class, then it might make sense to just add the object to the original class and recompile. That might be the way to go especially if this is a stand-alone app with no, or few, clients depending on it.
Alternatively, create a derived class e.g.
class C1 {
int i;
double d;
public:
C1(int x, double y) : i(x), d(y) {}
...
};
class C2 : public C1 {
std::string str; public:
C2(int x, double y, std::string z) :
C1(x, y), str(z) {}
}; With a derived class, there's no breakage for anything that's using a C1 . Anything that needs an "improved" C2 has the functionality required. Additionally, anything that expects a C1 can take a C2, but you do not have access to C2's extended functionalit.
If you mean something different, maybe you can create a (short) example of what you're trying to accomplish?
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
|
|
|
|
|
Thank you.
I am not that versatile to create derived class - but that is something I like to try.
I am pretty stuck with Qt and not sure how to physically accomplish the derivation.
At present I am testing the "add" using a library, mainly because
the library was tested long time ago.
|
|
|
|
|
Googling for something like "C++ derived class tutorial" should give you some useful hits.
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
|
|
|
|
|
jana_hus wrote: immature flaming responses will be as always ignored. as will yours.
|
|
|
|
|
Good afternoon,
a bit stumped with this one - any help would be greatly appreciated:
System.Void, System.Object, System.Inptr not defined or imported... a little bit stumped with this one... any help would be greatly be appreciated...
Regards,
Pieter Claassens
|
|
|
|
|
I think this is C#, not C++. C++ has no "Object" class, but it does have various integer types.
|
|
|
|
|
Without some context, it's almost impossible to figure out what you may be doing wrong.
Additionally, this looks like C#, not C++, so maybe in the wrong forum?
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
|
|
|
|
|
Apologies - this is a c# question ...
|
|
|
|
|
I have been searching for hours and i am having a really hard time finding any reference lists of theese legacy methods.
Basically what i am looking for is initializing graphics in DOS aka Dosbox or DOS boot disk for bootup.
I am looking for:
* BIOS registers for graphics modes and other useful things
* Methods to incorporate these registers in C with methods aka inline assembler
Please GOD make information about programming short and on point! Amen!
|
|
|
|
|
Alex D Aug2024 wrote: * BIOS registers for graphics modes and other useful things
Googling with the following seemed to return useful information
"BIOS" "graphics modes" PC-dos
Alex D Aug2024 wrote: Methods to incorporate these registers in C with methods aka inline assembler
Been a while but rather certain there was no remapping in the address space in 16 bit dos. Don't even think it was possible. Although perhaps 286/386 allowed that.
If it wasn't then you certainly did not need inline assembly. Because an address with, for example 0x10 was just a matter of initializing a pointer with exactly that address. Make sure it is a byte pointer.
|
|
|
|
|
Don't use the word "register". It doesn't apply in this case.
Search for "BIOS and DOS interrupts" and you'll find what you're looking for.
|
|
|
|
|
Let’s say I’m adding a derived class object to a vector that holds objects of base class type. STL vector allows me to do that without any explicit conversion. How do I revert the object inside a vector back to the derived class type? I’m only adding a pointer to the container not the actual object.
modified 12-Aug-24 10:26am.
|
|
|
|
|
|
So it works the same way. Got it.
|
|
|
|
|
Let me expand a bit on my previous answer[^].
As I said, you can convert a pointer (or reference) to pointer (or reference) to the base class. This called "upcasting" because you are moving "up" in the inheritance tree. The conversion is "non-destructive", in other words you can later on "downcast" (move from base to derived) as long as you know what type of object was in the first place. An example:
struct Unit {
Unit (int tag) : dog_tag(tag){};
virtual std::string kind () = 0;
int dog_tag;
};
struct Soldier : public Unit {
Soldier (int tag) : Unit(tag) {};
virtual std::string kind() {return "soldier";};
float running_speed;
}
struct Sailor : public Unit {
Sailor (int tag) : Unit(tag) {};
virtual std::string kind() {return "sailor";}
int life_jackets;
};
std::vector<Unit*> actors {new Soldier(555), new Sailor(666);};
int main () {
Unit* u0 = actors[0];
std::cout << "Actor 0 is a " << u0.kind() " with tag " << u0.dog_tag << std::endl;
If you would look with a debugger at u0 you would see a memory layout something like this:
-------- ------------------------------
u0| 0x1234 |------->| pointer to vtable of Soldier |
-------- |------------------------------|
| dog_tag |
| -----------------------------|
| running_speed |
------------------------------
You can see now why the code works: no matter what kind of object you deal with, the first part of the memory layout is the same. Compiler simply ignores whatever is after the dog_tag field.
A few more lines of code (please ignore that I didn't initialize other fields):
Soldier *s = (Soldier *)u0;
std::cout << "Running speed " << s->running_speed << std::endl; s has exactly the same value as u0 but compiler considers it a pointer to a Soldier object so it uses the value from the running_speed field. I could have written:
Sailor *ss = (Sailor*)u0;
std::cout << "Sailor has " << ss->life_jackets << " life jackets"; And compiler wouldn't have cared at all. It would have accessed the memory at life_jackets location as an integer and this is that.
Now, what happens if I use dynamic_cast instead of C-style casts?
Sailor *ss = dynamic_cast<Sailor*>(u0) The generated code would have used the value stored in the vtable member to check if the 0x1234 truly is a Sailor object. As the vtable value doesn't match the address of vtable for Sailor objects, the dynamic cast operation would have returned a NULL pointer.
Things to remember from this story:
- upcast is always safe. Downcast not so much.
- dynamic_cast is safer than C-style cast provided you check the result.
- dynamic_cast works only for classes that have at least one virtual function. If your object doesn't have a virtual table compiler cannot figure out what type of object it really is.
Mircea
|
|
|
|
|
The intelisense was bogus - I missed including "ui" header.
Thanks for all the help, it is much appreciated.
modified 10-Aug-24 22:07pm.
|
|
|
|
|
|
As a rule, I don't post a reply unless I can really answer the original question. I'm going to make an exception this time hoping that you will find my comments useful.
1. After you finished your question, look at it through the eyes of a stranger and ask yourself if he/she has enough information to answer it or if it is too much information. In this case "I have a working "connect" within an object and need to extend it to "connect" between objects." Doesn't tell me much I would have to learn Qt and, as you properly noticed, Qt is not a favourite around here. If it's a C++ question show the relevant C++ fragment followed by a pseudo-code of what you try to accomplish.
2. Format your code properly. Use the toolbar to wrap code fragments in <pre lang="C++"></pre> tags and indent your code to make it easier to read. I know it is a bit of work involved but doing it, shows that you care about your question otherwise, if you don't care about the question, other people might not care to answer it.
Please rephrase your question as a C++ one and I'll do my best to try to answer it. Surely other people, with even more expertise will do the same.
Mircea
|
|
|
|
|
Please stop deleting your questions, as it makes the replies impossible to understand. You have been here long enough, in all your different names, to know how this site works.
|
|
|
|
|
DELETED
-- modified 10-Aug-24 12:52pm.
|
|
|
|
|
Your code snippet is very difficult to read with all of the comments and lack of indentation.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|