I'm trying to learn C++, Thanks to this article I find many similarity between C++ and Python and Javascript: http://www.cse.msu.edu/~cse231/python2Cpp.html
But I can't understand C++ Classes at all, they looks like Javascript prototypes, but not that easy.
For example:
//CLxLogMessage defined in header
class myLOG: public CLxLogMessage{
public:
virtual const char * GetFormat (){
return "Wavefront Object";
}
void Error (const std::string &msg){
CLxLogMessage::Error (msg.c_str ());
}
void Info (const std::string &msg){
CLxLogMessage::Info (msg.c_str ());
}
private:
std::string authoringTool;
};
Question: What is this Public/Private stuff at all!?
Edit: To be honest, I more enjoy C++ than Python, because I can learn truth meaning of everything, not simple automated commands, for example I preferred to use "int X" rather than "X" alone.
Thanks
myLOG is the name of the class. It inherits (look it up2) from CLxLogMessage and has the functions GetFormat (which is virtual and can be overridden by subclasses and called through base class pointers, look it up2), Error, and Info. It has the data member authoringTool which is a string.
The public and private stuff is access specifiers. Something in the private section can only be used by the class's member functions, and stuff in the public section can be used by anybody. There is another type of section called protected which means that only a class and its subclasses can access it, but nobody else1.
If you start adding stuff to a class without setting an access level first, it defaults to private.
You can have as many public, private, and protected sections as you want, in any order.
You need these different protection levels because you don't want other people messing with your data when you don't know about it. For example, if you had a class representing fractions, you wouldn't want someone to change the denominator to a 0 right under your nose. They'd have to go through a setter function which would check that the new value was valid before setting the denominator to it. That's just a trivial example though. The fact that Python does not have these is a shortcoming in the language's design.
All your questions would be answered if you had read a C++ book. There is no easy way out with C++. If you try to take one, you'll end up being a horrible C++ programmer.
1 You can let somebody else access private and protected members by declaring them as friends (look it up2).
2 Sorry for saying "look it up" so much, but it's too much information for me to put here. You'll have to find a good resource for these kinds of things.
Even though there's no way to give a comprehensive answer or anything near that, maybe think about it like this: classes are types. Consider this:
int n;
Here "int" is the name of a type, and "x" is a variable of type "int". There are basic types in C++, like "int", "char", "double". Now we can also make new, compound types from old types:
struct Foo
{
int n;
char c;
double d;
};
This defines a new type called "Foo", and Foo x; makes a new variable of that type. Now we can add some magic to the type "Foo":
class Foo
{
int n;
double d;
public:
Foo() : n(20), d(0.5) { } // "constructor"
};
The keywords struct and class almost mean the same thing, so we still have a compound type that has two member variables, n and d. However, this type also has a member function, and this one gets called every time you create a new Foo object. So when you say, Foo x;, then this variable's member value x.n will be set to 20 and x.d will be set to 0.5.
So that's that in a nutshell: Classes are types with built-in magic. And you are the magician.
The private and public is to do with data encapsulation, it means you can change the implementation of the class without affecting how it is used. I suggest reading up on some of the theory of object orientation.
Related
Problem
I would like to detect if a class has member variables and fail a static assert if they do. Something like:
struct b {
int a;
}
static_assert(!has_member_variables<b>, "Class should not contain members"). // Error.
struct c {
virtual void a() {}
void other() {}
}
static_assert(!has_member_variables<c>, "Class should not contain members"). // Fine.
struct d : c {
}
static_assert(!has_member_variables<d>, "Class should not contain members"). // Fine.
struct e : b {
}
static_assert(!has_member_variables<e>, "Class should not contain members"). // Error.
struct f : c {
char z;
}
static_assert(!has_member_variables<f>, "Class should not contain members"). // Error.
Is there a way to achieve this with SFINAE template? This class may have inheritance or even multiple inheritance with virtual functions (no members in the base classes though).
Motivation
I have a pretty simple setup as follows:
class iFuncRtn {
virtual Status runFunc(Data &data) = 0;
};
template <TRoutine, TSpecialDataType>
class FuncRoutineDataHelper : public iFuncRtn {
Status runFunc(Data &data) {
static_assert(!has_member_variables<TRoutine>, "Routines shouldnt have data members!");
// Prepare special data for routine
TSpecialDataType sData(data);
runFuncImpl(sData);
}
class SpecificRtn :
public FuncRoutineDataHelper<SpecificRtn, MySpecialData> {
virtual Status runFuncImpl(MySpecialData &sData) {
// Calculate based on input
sData.setValue(someCalculation);
}
};
The FunctionalityRoutines are managed and run on a per tick basis. They are customized and can perform a wide variety of tasks such as contacting other devices etc. The data that is passed in can be manipulated by the routine and is guaranteed to be passed in on each tick execution until the functionality is finished. The right type of data is passed in based on the DataHelper class. I wan't to discourage future people from mistakenly adding data to the functionality routines as it is very unlikely to do what they expect. To force this, I was hoping to find a way with static assert.
You can solve this by depending on the compiler doing empty base class optimizations, by checking if a class derived from your T has the same size as an empty class with virtual functions:
template<typename T, typename... BaseClasses>
class IsEmpty
{
// sanity check; see the updated demo below
static_assert(IsDerivedFrom<T, BaseClasses...>::value);
struct NonDerived : BaseClasses... { virtual ~NonDerived() = default; };
struct Derived : T { virtual ~Derived() = default; };
public:
inline static constexpr bool value = (sizeof(NonDerived) == sizeof(Derived));
};
This should work with both single and multiple inheritance. However, when using multiple inheritance, it's necessary to list all base classes, like that:
static_assert(IsEmpty<Derived, Base1, Base2, Base3>::value);
Obviously, this solution rules out final classes.
Here's the updated demo.
Here's the original demo. (doesn't work with multiple inheritance)
You will have to mark the classes in some way or another. Pick a way you are comfortable with, a property or some kind of type integer member with an enum. Whoever makes sub-classes will have to follow your convention to make it work.
All other answers here will be some variant of this.
Any answer that uses a sizeof could not guarantee this will work between platforms, compilers, or even classes on the same platform and compiler, due to easily being able to fit a new member inside the default class member alignment, where the sizes of sizeof could easily end up the same for a sub-class.
Background:
As stated in your code and question, all of that is just plain and basic C ad C++ code, and is resolved entirely at compile time. The compiler will tell you if a member exists or not. After its compiled it's a mash of efficient, nameless, machine code with no hints or help for that kind of thing by itself.
Any name you use for a function or data member effectively disappears, as you know it and see it there, after compile and there is no way to lookup any member by name. Each data member is known only by its numerical offset from the top of the class or struct.
Systems like .Net, Java, and others are designed for reflection, which is the ability to remember class members by name, where you can find them at runtime when you program is running.
Templates in C++, unless mixed mode C++ on something like .Net, are also all resolved at compile time, and the names will also all be gone, so the templates by themselves buy you nothing.
Languages like Objective-C also are written to not fail necessarily if certain types of special members are missing, similar to what you are asking, but under the covers its using a lot of supporting code and runtime management to keep track independently, where the actual function itself and its code are still unware and rely on other code to tell them if a member exists or to not fail on null member.
In pure C or C++ you will need to just make your own system, and be literal about tracking dynamically what does what. You could make enums, or lists or dictionaries of name strings. This is what is normally done, you just have to leave hints for yourself. A class cannot be compiled in a way that gives implicit visibility to future sub-classes by definition, without using some form if RTTI.
Its common to put a type member on a class for this very reason, which could be a simple enum. I would not count on sizes or anything that might be platform dependent.
This is really a question of good form/best practices. I use structs in C++ to form objects that are designed to basically hold data, rather than making a class with a ton of accessor methods that do nothing but get/set the values. For example:
struct Person {
std::string name;
DateObject dob;
(...)
};
If you imagine 20 more variables there, writing this as a class with private members and 40-something accessors is a pain to manage and seems wasteful to me.
Sometimes though, I might need to also add some sort of minimal functionality to the data. In the example, say I also sometimes need the age, based on dob:
struct Person {
std::string name;
DateObject dob;
(...)
int age() {return calculated age from dob;}
}
Of course for any complex functionality I would make a class, but for just a simple functionality like this, is this "bad design"? If I do use a class, is it bad form to keep the data variables as public class members, or do I just need to accept it and make classes with a bunch of accessor methods? I understand the differences between classes and structs, I'm just asking about best practices.
I think there are two important design principles to consider here:
Hide a class's representation through an interface if there is some invariant on that class.
A class has an invariant when there is such thing as an invalid state for that class. The class should maintain its invariant at all times.
Consider a Point type that represents a 2D geometric point. This should just be a struct with public x and y data members. There is no such thing as an invalid point. Every combination of x and y values is perfectly fine.
In the case of a Person, whether it has invariants depends entirely on the problem at hand. Do you consider such things as an empty name as a valid name? Can the Person have any date of birth? For your case, I think the answer is yes and your class should keep the members public.
See: Classes Should Enforce Invariants
Non-friend non-member functions improve encapsulation.
There's no reason your age function should be implemented as a member function. The result of age can be calculated using the public interface of Person, so it has no reason to be a member function. Place it in the same namespace as Person so that it is found by argument-dependent lookup. Functions found by ADL are part of the interface of that class; they just don't have access to private data.
If you did make it a member function and one day introduced some private state to Person, you would have an unnecessary dependency. Suddenly age has more access to data than it needs.
See: How Non-Member Functions Improve Encapsulation
So here's how I would implement it:
struct Person {
std::string name;
DateObject dob;
};
int age(const Person& person) {
return calculated age from person.dob;
}
In C++, Structs are classes, with the only difference (that I can think of, at least) being that in Structs members are public by default, but in classes they are private. This means it is perfectly acceptable to use Structs as you are - this article explains it well.
In C++, the only difference between structs and classes are that structs are publicly visibly by default. A good guideline is to use structs as plain-old-data (POD) that only hold data and use classes for when more functionality (member functions) is required.
You may still be wondering whether to just have public variables in the class or use member functions; consider the following scenario.
Let's say you have a class A that has a function GetSomeVariable that is merely a getter for a private variable:
class A
{
double _someVariable;
public:
double GetSomeVariable() { return _someVariable; }
};
What if, twenty years down the line, the meaning of that variable changes, and you have to, let's say, multiply it by 0.5? When using a getter, it is simple; just return the variable multiplied by 0.5:
double GetSomeVariable() { return 0.5*_someVariable; }
By doing this, you allow for easy maintainability and allow for easy modification.
If you want some data holder then prefer struct without any get/set methods.
If there is more to it, as in this case "Person".
It models real world entity,
Has definite state and behaviour,
Interacts with external world,
Exhibits simple/complex relationship with other entities,
it may evolve overtime,
then it is a perfect candidate for a class.
"Use a struct only for passive objects that carry data; everything else is a class."
say google guidlines, I do it this way and find it a good rule. Beside that I think you can define your own pragmatics, or deviate from this rule if it really makes sense.
I don't want to sparkle a holy war here; I usually differentiate it in this way:
For POD objects (i.e., data-only, without exposed behavior) declare the internals public and access them directly. Usage of struct keyword is convenient here and also serves as a hint of the object usage.
For non-POD objects declare the internals private and define public getters/setters. Usage of class keyword is more natural in these cases.
For just clearing the confusion for some! And easy picking! Here some points!
In struct! you can have encapsulation and visibility operators (make private or public)! Just like you do with classes!
So the statement that some say or you may find online that say: one of the differences is that structures have no visibility operator and ability to hide data, is wrong!
You can have methods just like in classes!
Run the code bellow! And you can check it compiles all well! And run all well! And the whole struct work just like class!
Mainly the difference is just in the defaulting of the visibility mode!
Structures have it public! Classes privates by default!
#include<iostream>
#include<string>
using namespace std;
int main(int argv, char * argc[]) {
struct {
private:
bool _iamSuperPrivate = true;
void _sayHallo() {
cout << "Hallo mein Bruder!" << endl;
}
public:
string helloAddress = "";
void sayHellow() {
cout << "Hellow!" << endl;
if (this->helloAddress != "") {
cout << this->helloAddress << endl;
}
this->_sayHallo();
}
bool isSuperPrivateWorking() {
return this->_iamSuperPrivate;
}
} testStruct;
testStruct.helloAddress = "my Friend!";
testStruct.sayHellow();
if (testStruct.isSuperPrivateWorking()) {
cout << "Super private is working all well!" << endl;
} else {
cout << "Super private not working LOL !!!" << endl;
}
return 0;
}
In memory they are the same!
I didn't check myself! But some say if you make the same thing! The compiled assembly code will come the same between a struct and a class! (to be checked!)
Take any class and change the name to typedef struct ! You'll see that the code will still works the same!
class Client {
}
Client client(...);
=>
typedef struct Client {
....
} Client;
Client client(...);
If you do that all will works the same! At least i know that does in gcc!
YOu can test! In your platform!
I've recently spent a lot of time with javascript and am now coming back to C++. When I'm accessing a class member from a method I feed inclined to prefix it with this->.
class Foo {
int _bar;
public:
/* ... */
void setBar(int bar) {
this->_bar = bar;
// as opposed to
_bar = bar;
}
}
On reading, it saves me a brain cycle when trying to figure out where it's coming from.
Are there any reasons I shouldn't do this?
Using this-> for class variables is perfectly acceptable.
However, don't start identifiers with an underscore, or include any identifiers with double underscore __ anywhere. There are some classes of reserved symbols that are easy to hit if you violate either of these two rules of thumb. (In particular, _IdentifierStartingWithACapital is reserved by the standard for compilers).
In principle, accessing members via this-> is a coding style that can help in making things clearer, but it seems to be a matter of taste.
However, you also seem to use prefixing members with _ (underscore). I would say that is too much, you should go for either of the two styles.
Are there any reasons I shouldn't do this?
Yes, there is a reason why you shouldn't do this.
Referencing a member variable with this-> is strictly required only when a name has been hidden, such as with:
class Foo
{
public:
void bang(int val);
int val;
};
void Foo::bang(int val)
{
val = val;
}
int main()
{
Foo foo;
foo.val = 42;
foo.bang(84);
cout << foo.val;
}
The output of this program is 42, not 84, because in bang the member variable has been hidden, and val = val results in a no-op. In this case, this-> is required:
void Foo::bang(int val)
{
this->val = val;
}
In other cases, using this-> has no effect, so it is not needed.
That, in itself, is not a reason not to use this->. The maintennance of such a program is however a reason not to use this->.
You are using this-> as a means of documentation to specify that the vairable that follows is a member variable. However, to most programmers, that's not what usign this-> actually documents. What using this-> documents is:
There is a name that's been hidden here, so I'm using a special
technique to work around that.
Since that's not what you wanted to convey, your documentation is broken.
Instead of using this-> to document that a name is a member variable, use a rational naming scheme consistently where member variables and method parameters can never be the same.
Edit Consider another illustration of the same idea.
Suppose in my codebase, you found this:
int main()
{
int(*fn)(int) = pingpong;
(fn)(42);
}
Quite an unusual construct, but being a skilled C++ programmer, you see what's happening here. fn is a pointer-to-function, and being assigned the value of pingpong, whatever that is. And then the function pointed to by pingpong is being called with the singe int value 42. So, wondering why in the world you need such a gizmo, you go looking for pingpong and find this:
static int(*pingpong)(int) = bangbang;
Ok, so what's bangbang?
int bangbang(int val)
{
cout << val;
return val+1;
}
"Now, wait a sec. What in the world is going on here? Why do we need to create a pointer-to-function and then call through that? Why not just call the function? Isn't this the same?"
int main()
{
bangbang(42);
}
Yes, it is the same. The observable effects are the same.
Wondering if that's really all there is too it, you see:
/* IMPLEMENTATION NOTE
*
* I use pointers-to-function to call free functions
* to document the difference between free functions
* and member functions.
*/
So the only reason we're using the pointer-to-function is to show that the function being called is a free function
and not a member function.
Does that seem like just a "matter of style" to you? Because it seems like insanity to me.
Here you will find:
Unless a class member name is hidden, using the class member name is equivalent to using the class member name with the this pointer and the class member access operator (->).
I think you do this backwards. You want the code to assure you that what happens is exactly what is expected.
Why add extra code to point out that nothing special is happening? Accessing class members in the member functions happen all the time. That's what would be expected. It would be much better to add extra info when it is not the normal things that happen.
In code like this
class Foo
{
public:
void setBar(int NewBar)
{ Bar = NewBar; }
you ask yourself - "Where could the Bar come from?".
As this is a setter in a class, what would it set if not a class member variable?! If it wasn't, then there would be a reason to add a lot of info about what's actually going on here!
Since you are already using a convention to signify that an identifer is a data member (although not one I would recommend), adding this-> is simply redundant in almost all cases.
This is a somewhat subjective question obvously. this-> seems much more python-idiomatic than C++-idiomatic. There are only a handful of cases in C++ where the leading this-> is required, dealing with names in parent template classes. In general if your code is well organized it will be obvious to the reader that it's a member or local variable (globals should just be avoided), and reducing the amount to be read may reduce complexity. Additionally you can use an optional style (I like trailing _) to indicate member variables.
It doesn't actually harm anything, but programmers experienced with OO will see it and find it odd. It's similarly surprising to see "yoda conditionals," ie if (0 == x).
Several questions about accessor methods in C++ have been asked on SO, but none was able satisfy my curiosity on the issue.
I try to avoid accessors whenever possible, because, like Stroustrup and other famous programmers, I consider a class with many of them a sign of bad OO. In C++, I can in most cases add more responsibility to a class or use the friend keyword to avoid them. Yet in some cases, you really need access to specific class members.
There are several possibilities:
1. Don't use accessors at all
We can just make the respective member variables public. This is a no-go in Java, but seems to be OK with the C++ community. However, I'm a bit worried about cases were an explicit copy or a read-only (const) reference to an object should be returned, is that exaggerated?
2. Use Java-style get/set methods
I'm not sure if it's from Java at all, but I mean this:
int getAmount(); // Returns the amount
void setAmount(int amount); // Sets the amount
3. Use objective C-style get/set methods
This is a bit weird, but apparently increasingly common:
int amount(); // Returns the amount
void amount(int amount); // Sets the amount
In order for that to work, you will have to find a different name for your member variable. Some people append an underscore, others prepend "m_". I don't like either.
Which style do you use and why?
From my perspective as sitting with 4 million lines of C++ code (and that's just one project) from a maintenance perspective I would say:
It's ok to not use getters/setters if members are immutable (i.e. const) or simple with no dependencies (like a point class with members X and Y).
If member is private only it's also ok to skip getters/setters. I also count members of internal pimpl-classes as private if the .cpp unit is smallish.
If member is public or protected (protected is just as bad as public) and non-const, non-simple or has dependencies then use getters/setters.
As a maintenance guy my main reason for wanting to have getters/setters is because then I have a place to put break points / logging / something else.
I prefer the style of alternative 2. as that's more searchable (a key component in writing maintainable code).
2) is the best IMO, because it makes your intentions clearest. set_amount(10) is more meaningful than amount(10), and as a nice side effect allows a member named amount.
Public variables is usually a bad idea, because there's no encapsulation. Suppose you need to update a cache or refresh a window when a variable is updated? Too bad if your variables are public. If you have a set method, you can add it there.
I never use this style. Because it can limit the future of your class design and explicit geters or setters are just as efficient with a good compilers.
Of course, in reality inline explicit getters or setters create just as much underlying dependency on the class implementation. THey just reduce semantic dependency. You still have to recompile everything if you change them.
This is my default style when I use accessor methods.
This style seems too 'clever' to me. I do use it on rare occasions, but only in cases where I really want the accessor to feel as much as possible like a variable.
I do think there is a case for simple bags of variables with possibly a constructor to make sure they're all initialized to something sane. When I do this, I simply make it a struct and leave it all public.
That is a good style if we just want to represent pure data.
I don't like it :) because get_/set_ is really unnecessary when we can overload them in C++.
STL uses this style, such as std::streamString::str and std::ios_base::flags, except when it should be avoided! when? When method's name conflicts with other type's name, then get_/set_ style is used, such as std::string::get_allocator because of std::allocator.
In general, I feel that it is not a good idea to have too many getters and setters being used by too many entities in the system. It is just an indication of a bad design or wrong encapsulation.
Having said that, if such a design needs to be refactored, and the source code is available, I would prefer to use the Visitor Design pattern. The reason is:
a. It gives a class an opportunity to
decide whom to allow access to its
private state
b. It gives a class an
opportunity to decide what access to
allow to each of the entities who are
interested in its private state
c. It
clearly documents such exteral access
via a clear class interface
Basic idea is:
a) Redesign if possible else,
b)
Refactor such that
All access to class state is via a well known individualistic
interface
It should be possible to configure some kind of do's and don'ts
to each such interface, e.g. all
access from external entity GOOD
should be allowed, all access from
external entity BAD should be
disallowed, and external entity OK
should be allowed to get but not set (for example)
I would not exclude accessors from use. May for some POD structures, but I consider them a good thing (some accessors might have additional logic, too).
It doesn't realy matters the naming convention, if you are consistent in your code. If you are using several third party libraries, they might use different naming conventions anyway. So it is a matter of taste.
I've seen the idealization of classes instead of integral types to refer to meaningful data.
Something like this below is generally not making good use of C++ properties:
struct particle {
float mass;
float acceleration;
float velocity;
} p;
Why? Because the result of p.mass*p.acceleration is a float and not force as expected.
The definition of classes to designate a purpose (even if it's a value, like amount mentioned earlier) makes more sense, and allow us to do something like:
struct amount
{
int value;
amount() : value( 0 ) {}
amount( int value0 ) : value( value0 ) {}
operator int()& { return value; }
operator int()const& { return value; }
amount& operator = ( int const newvalue )
{
value = newvalue;
return *this;
}
};
You can access the value in amount implicitly by the operator int. Furthermore:
struct wage
{
amount balance;
operator amount()& { return balance; }
operator amount()const& { return balance; }
wage& operator = ( amount const& newbalance )
{
balance = newbalance;
return *this;
}
};
Getter/Setter usage:
void wage_test()
{
wage worker;
(amount&)worker = 100; // if you like this, can remove = operator
worker = amount(105); // an alternative if the first one is too weird
int value = (amount)worker; // getting amount is more clear
}
This is a different approach, doesn't mean it's good or bad, but different.
An additional possibility could be :
int& amount();
I'm not sure I would recommend it, but it has the advantage that the unusual notation can refrain users to modify data.
str.length() = 5; // Ok string is a very bad example :)
Sometimes it is maybe just the good choice to make:
image(point) = 255;
Another possibility again, use functional notation to modify the object.
edit::change_amount(obj, val)
This way dangerous/editing function can be pulled away in a separate namespace with it's own documentation. This one seems to come naturally with generic programming.
Let me tell you about one additional possiblity, which seems the most conscise.
Need to read & modify
Simply declare that variable public:
class Worker {
public:
int wage = 5000;
}
worker.wage = 8000;
cout << worker.wage << endl;
Need just to read
class Worker {
int _wage = 5000;
public:
inline int wage() {
return _wage;
}
}
worker.wage = 8000; // error !!
cout << worker.wage() << endl;
The downside of this approach is that you need to change all the calling code (add parentheses, that is) when you want to change the access pattern.
variation on #3, i'm told this could be 'fluent' style
class foo {
private: int bar;
private: int narf;
public: foo & bar(int);
public: int bar();
public: foo & narf(int);
public: int narf();
};
//multi set (get is as expected)
foo f; f.bar(2).narf(3);
I read that early C++ "compilers" actually translated the C++ code to C and used a C compiler on the backend, and that made me wonder. I've got enough technical knowledge to wrap my head around most of how that would work, but I can't figure out how to do class inheritance without having language support for it.
Specifically, how do you define a class with a few fields, then a bunch of subclasses that inherit from it and each add their own new fields, and be able to pass them around interchangeably as function arguments? And especially how can you do it when C++ allows you to allocate objects on the stack, so you might not even have pointers to hide behind?
NOTE: The first couple answers I got were about polymorphism. I know all about polymorphism and virtual methods. I've even given a conference presentation once about the low-level details of how the virtual method table in Delphi works. What I'm wondering about is class inheritance and fields, not polymorphism.
In C anyway you an do it the way cfront used to do it in the early days of C++ when the C++ code was translated into C. But you need to be quite disciplined and do all the grunt work manually.
Your 'classes' have to be initialized using a function that performs the constructor's work. this will include initializing a pointer to a table of polymorphic function pointers for the virtual functions. Virtual function calls have to be made through the vtbl function pointer (which will point to a structure of function pointers - one for each virtual function).
The virtual function structure for each derived calss needs to be a super-set of the one for the base class.
Some of the mechanics of this might be hidden/aided using macros.
Miro Samek's first edition of "Practical Statecharts in C/C++" has an Appendix A - "C+ - Object Oriented Programming in C" that has such macros. It looks like this was dropped from the second edition. Probably because it's more trouble than it's worth. Just use C++ if you want to do this...
You should also read Lippman's "Inside the C++ Object Model" which goes into gory details about how C++ works behind the scenes, often with snippets of how things might work in C.
I think I see what you're after. Maybe.
How can something like this work:
typedef
struct foo {
int a;
} foo;
void doSomething( foo f); // note: f is passed by value
typedef
struct bar {
foo base;
int b;
} bar;
int main() {
bar b = { { 1 }, 2};
doSomething( b); // how can the compiler know to 'slice' b
// down to a foo?
return 0;
}
Well you can't do that as simply as that without language support - you'd need to do some things manually (that's what it means to not have language support):
doSomething( b.base); // this works
Basically, structs-within-structs.
struct Base {
int blah;
};
struct Derived {
struct Base __base;
int foo;
};
When you want to, say, cast a Derived * to Base *, you'd actually return a pointer to the __base element of the Derived struct, which in this case is the first thing in the struct so the pointers should be the same (wouldn't be the case for multiple-inherited classes though).
If you want to access blah in this case, you would do something like derived.__base.blah.
Virtual functions are normally done with a special table of function pointers that is part of each object, a rudimentary sort of "what is my type" record.
Here is how COM does it for C language. I am a bit rusty at this , but the essence works like this. Each "class" member variables is just a struct.
struct Shape
{
int value;
};
struct Square
{
struct Shape shape; // make sure this is on top, if not KABOOM
int someothervalue;
};
all the methods, are actually just normal functions. like this
void Draw(Shape * shape,int x,int y)
{
shape->value=10; // this should work even if you put in a square. i think...
}
then, they use the preprocessor to "trick" the C code into displaying something like this.
Square * square;
square->Draw(0,0); // this doesnt make sense, the preprocessor changes it to Draw(square,0,0);
Alas, i dont know what kind of preprocessor tricks are done to make the C++ looking function call resolve into a plan vanilla C call.
DirectX COM objects are declared this way.
Dr. Dobb's had a moderately detailed article on this topic, Single Inheritance Classes in C.
Structs-within-structs is common, but it makes it a pain to access inherited fields. You either need to use indirection (e.g. child->parent.field), or casting (((PARENT *) child)->field).
An alternative I have seen is more like this:
#define COUNTRY_FIELDS \
char *name; \
int population;
typedef struct COUNTRY
{
COUNTRY_FIELDS
} COUNTRY;
#define PRINCIPALITY_FIELDS \
COUNTRY_FIELDS \
char *prince;
typedef struct PRINCIPALITY
{
PRINCIPALITY_FIELDS
} PRINCIPALITY;
This gives types with direct access to inherited fields. The resulting objects can still be safely cast to the parent type, because the parent's fields and the inherited fields start at the same place.
The syntax can be improved a little with macros. I saw this in the older POV-Ray source (but I think they've since converted to C++).
If you want a good reference on how this stuff works take a look at the glib/gdk/gtk open source libraries. They have pretty good documentation and the entire framework is based on C OO.
You can simulate an object by writing constructors, setters, getters, and destructors with the hidden this pointer called out explicitly.
Inheritance is handled by having the derived object include a pointer to the base object in the structure of the derived object.