Why How to Define Structures and Classes Within a Function in C++

Define functions in structs

No, as functions are not data. But you can define function pointers inside a struct.

struct foo {
int a;
void (*workwithit)(struct foo *);
}

C - function inside struct

It can't be done directly, but you can emulate the same thing using function pointers and explicitly passing the "this" parameter:

typedef struct client_t client_t, *pno;
struct client_t
{
pid_t pid;
char password[TAM_MAX]; // -> 50 chars
pno next;

pno (*AddClient)(client_t *);
};

pno client_t_AddClient(client_t *self) { /* code */ }

int main()
{

client_t client;
client.AddClient = client_t_AddClient; // probably really done in some init fn

//code ..

client.AddClient(&client);

}

It turns out that doing this, however, doesn't really buy you an awful lot. As such, you won't see many C APIs implemented in this style, since you may as well just call your external function and pass the instance.

Are there any penalties for defining a struct inside a function?

In C++11, no - there's no penalty. I would even consider it a very good style to not pollute any "more visible" scopes with you implementation details, unless, of course, you want to reuse that functor elsewhere. However, lambdas are essentially a condensed form of this idea, and should usually be preferred if you are just using the struct as functor. For all kinds of data, it is perfectly fine, although it usually competes with std::pair and std::tuple in that aspect.

In C++03, you cannot use such a struct as a template parameter, since those parameters need to have external linkage (Visual Studio lets you do it anyways, though). It can still be useful to use such a struct with a polymorphic interface.

Can we define structs after the main function in C++?

Can we define struct after the main program in C++?

I presume that you mean the main function. Yes, we can define classes (including structs) after main function. A demo:

int main(){}
struct S{};

When we define functions, we can declare the function before the main program and then write the function definition after the main program. I wanted to know if we can do something similar to this when defining structures.

Same applies to classes, you can (forward) declare them before a function, and define after. However, the uses of an incomplete (declared but not defined) classes are quite limited. You can define pointers and references to them, but you cannot create them, or call any member functions. A demo:

struct S;     // (forward) declaration of a class
S* factory(); // (forward) declaration of a function
int main(){
S* s = factory(); // OK, no definition required
// s->foo(); // not OK, S is incomplete
// S s2; // not OK
}
struct S{ // definition of a class
void foo(); // declaration of a member function
};
S* factory() {
static S s; // OK, S is complete
s.foo(); // OK, note how the member function can be called
// before it is defined, just like free functions
return &s;
}
void S::foo() {} // definition of a member function

Can structures in C++ have functions inside?

A C struct cannot have member functions. (It can have function pointers, which however are not the same thing.)

A C++ struct is equivalent to a class in every way but the default visibility of its members, as stated by your book (public for struct, private for class), and its default inheritance.


class MyClass : public BaseClass
{
public:
MyClass();
virtual ~MyClass();

void someFunction();

private:
int member_;
};

In the above example, which does state visibility (public, private) explicitly instead of relying on defaults (a practice I endorse, for clarity), the keyword class could be swapped for struct without any change of meaning or result.

There is some understanding that struct is preferred for plain data collections, while class is preferred for fully-fledged classes with non-trivial functionality, but that is as far as it goes.


Perhaps your teacher was talking about C structs.

When should you use a class vs a struct in C++?

The differences between a class and a struct in C++ are:

  • struct members and base classes/structs are public by default.
  • class members and base classes/structs are private by default.

Both classes and structs can have a mixture of public, protected and private members, can use inheritance, and can have member functions.

I would recommend you:

  • use struct for plain-old-data structures without any class-like features;
  • use class when you make use of features such as private or protected members, non-default constructors and operators, etc.

why can't we declare functions inside a structure?

Well that is the fundamental difference between C and C++ (works in C++). C++ supports classes (and in C++ a struct is a special case of a class), and C does not.

In C you would implement the class as a structure with functions that take a this pointer explicitly, which is essentially what C++ does under the hood. Coupled with a sensible naming convention so you know what functions belong to which classes (again something C++ does under then hood with name-mangling), you get close to object-based if not object-oriented programming. For example:

typedef struct temp
{
int a;

} classTemp ;

void classTemp_GetData( classTemp* pThis )
{
printf( "Enter value of a : " );
scanf( "%d", &(pThis->a) );
}

classTemp T ;

int main()
{
classTemp_GetData( &T );
}

However, as you can see without language support for classes, implementing then can become tiresome.

In C, the functions and data structures are more or less bare; the language gives a minimum of support for combining data structures together, and none at all (directly) for including functions with those data structures.

The purpose of C is to have a language that translates as directly as possible into machine code, more like a portable assembly language than a higher-level language such as C++ (not that C++ is all that high-level). C let's you get very close to the machine, getting into details that most languages abstract away; the down side of this is that you have to get close to the machine in C to use the language to its utmost. It takes a completely different approach to programming from C++, something that the surface similarities between them hide.

Check out here for more info (wonderful discussions there).


P.S.: You can also accomplish the functionality by using function pointers, i.e.
have a pointer to a function (as a variable) inside the struct.

For example:

#include <stdio.h>

struct t {
int a;
void (*fun) (int * a); // <-- function pointers
} ;

void get_a (int * a) {
printf (" input : ");
scanf ("%d", a);
}

int main () {
struct t test;
test.a = 0;

printf ("a (before): %d\n", test.a);
test.fun = get_a;
test.fun(&test.a);
printf ("a (after ): %d\n", test.a);

return 0;
}


Related Topics



Leave a reply



Submit