Suppose I have nested classes as follows defined in a header file:
class ClassA
{
private:
class ClassB
{
private:
int member_b;
public:
void function_name();
};
};
In order to give a definition to the function "function_name()" in an external .cpp file, I have to access it like this:
void ClassA::ClassB::function_name()
{
std::cout << member_b;
return;
}
For the sake of this example, please do not ask why I'm using nested classes; I have a reason for doing so in my actual project. However, my question is this; is it possible to somehow shorten the ClassA::ClassB::function_name() in the implementation file to something like short::function_name() while still keeping the classes nested? I don't think that typedefs or new namespace definitions can help me here, but maybe I'm wrong.
Qualified type names allow you to define a typedef to represent a qualified class name. You can then use the typedef with the :: (scope resolution) operator to refer to a nested class or class member, as shown in the following example:
class outside
{
public:
class nested
{
public:
static int x;
static int y;
int f();
int g();
};
};
int outside::nested::x = 5;
int outside::nested::f() { return 0; };
typedef outside::nested outnest; // define a typedef
int outnest::y = 10; // use typedef with ::
int outnest::g() { return 0; };
However, using a typedef to represent a nested class name hides information and may make the code harder to understand.
Source : https://www.ibm.com/support/knowledgecenter/en/SSPSQF_9.0.0/com.ibm.xlcpp111.aix.doc/language_ref/cplr061.html
Have you tried using aliases?
// C++11
using fmtfl = std::ios_base::fmtflags;
// C++03 equivalent:
// typedef std::ios_base::fmtflags fmtfl;
fmtfl fl_orig = std::cout.flags();
fmtfl fl_hex = (fl_orig & ~std::cout.basefield) | std::cout.showbase | std::cout.hex;
// ...
std::cout.flags(fl_hex);
Code source: https://msdn.microsoft.com/en-us/library/dn467695.aspx
The question is simple, I guess I cannot do this: (Im in the header file)
typedef struct {
myclass *p;
...
} mystruct;
class myclass {
private:
mystruct *s;
...
}
Because when the compiler reaches the struct it doesnt know what myclass is, but I cannot do the reverse either for the same reason:
class myclass {
private:
mystruct *s;
...
}
typedef struct {
myclass *p;
...
} mystruct;
How can I make that possible ? Im guessing there is some way to say the compiler "There is an struct called mystruct" before the class (2 example) so it knows that mystruct *s it's possible but I cant manage to do it right. Thanks
You need to use a forward declaration:
class myclass;
typedef struct {
myclass *p;
...
} mystruct;
class myclass {
private:
mystruct *s;
...
}
Now the compiler knows that myclass is a class when it first sees it.
Also, no need to typedef structs in C++. You can simply write:
struct mystruct {
myclass *p;
...
};
Which does the same.
In general, it is possible to declare a pointer to a class that has not been defined yet. You need only to have "declared" the class (class myclass).
This is the general solution to define classes with cross-references.
First of all, typedefs shouldn't be used anymore in modern C++ (there is better syntax). For structs just use:
struct mystruct {
...
}
Also maybe consider a redesign so that you don't have 2 types dependent on each other. If it's not possible, then as others have said forward declare the types before.
I have the following situation:
typedef void (*F_POINTER)(ClassName*);
class ClassName {
public:
F_POINTER f;
}
This happens because an instance of ClassName needs to pass a pointer itself to the client. However, If I write things in this order, I get complains about ClassName not declared, whatnot. However, if I switch them around, I get complains about F_POINTER not being declared when I declare the instance in the class.
So maybe I'm missing something simple here, but how would I accomplish this?
Forward declaration:
class ClassName;
typedef (*F_POINTER)(ClassName*);
class ClassName {
public:
F_POINTER f;
}
Or shorter:
typedef (*F_POINTER)(class ClassName*); // implicit declaration;
This seems to be working under GCC 4.5.2 (mingw32):
typedef void (*F_POINTER)(class ClassName);
class ClassName {};
void f (ClassName) {}
int main ()
{
F_POINTER x = f;
}
I wouldn't trust my life on whether it is legal C++ or not, not even the pointer version described by other people. Forward declarations and pointers do not solve everything, for example it is not possible to declare methods that throw pointers of incomplete types, you need full definition for that. This might be similarly illegal, just accepted by compilers.
Forward declare ClassName. The type can be incomplete to use a pointer to it.
class ClassName;
typedef (*F_POINTER)(ClassName*);
class ClassName { ... };
Alternatively, move the typedef inside the class. Also consider using boost::function/std::function instead of function pointers.
Either you can forward declare it as,
class ClassName;
typedef void (*F_POINTER)(ClassName*); // assume that return is `void`
before the F_POINTER or you can use the template trick to avoid such hassels for every class:
template<typename RETURN, typename ARGUMENT>
struct FuncPtr { typedef RETURN (*F_POINTER)(ARGUMENT); };
Usage:
class ClassName {
public:
FuncPtr<void,ClassName*>::F_POINTER f;
};
I have seen following style class definition several times. What exactly are the pros/cons of this style?
typedef class _MyClass
{
public :
_MyClass();
} MyClass;
It's pretty rare in C++, but common in C (where struct Foo does not automatically alias to just Foo.) You might see it in a library that has different classes for different platforms (e.g. a "Canvas" class, which is very implementation-specific.) The library would use the typedef to let its users simplify their code:
#if WINDOWS
typedef class WindowsCanvas {
private: HWND handle;
} Canvas;
#elif MAC
typedef class MacCanvas {
private: CGContextRef context;
} Canvas;
#endif
In such an example, one would only need to use the Canvas type, never the platform-specific types.
In C++ there are no pros. This style came from C where you couldn't just use the struct's name as a type. E.g.
struct X
{
int x;
};
X a; //compiler error
struct X b; //OK
in order to avoid using the elaborated type specifier, like struct X a, or enum E e; etc. in C it is a common practice to typedef the name.
E.G.
typedef struct X_ { ... } X;
Now X a; is OK too.
Naturally in C++ there is no need to do this.
One possible advantage is illustrated by a highly contrived example, but since the Standard speaks of it, it must be having an impliciation for sure.
$7.1.3/6- "Similarly, in a given
scope, a class or enumeration shall
not be declared with the same name as
a typedef-name that is declared in
that scope and refers to a type other
than the class or enumeration itself.
[
typedef struct S{} MYS;
int MYS; // Error due to $7.1.3/6
struct A{};
int A; // No error, subsequent use required fully elaborated name
int main(){}
Can a struct have a constructor in C++?
I have been trying to solve this problem but I am not getting the syntax.
In C++ the only difference between a class and a struct is that members and base classes are private by default in classes, whereas they are public by default in structs.
So structs can have constructors, and the syntax is the same as for classes.
struct TestStruct {
int id;
TestStruct() : id(42)
{
}
};
All the above answers technically answer the asker's question, but just thought I'd point out a case where you might encounter problems.
If you declare your struct like this:
typedef struct{
int x;
foo(){};
} foo;
You will have problems trying to declare a constructor. This is of course because you haven't actually declared a struct named "foo", you've created an anonymous struct and assigned it the alias "foo". This also means you will not be able to use "foo" with a scoping operator in a cpp file:
foo.h:
typedef struct{
int x;
void myFunc(int y);
} foo;
foo.cpp:
//<-- This will not work because the struct "foo" was never declared.
void foo::myFunc(int y)
{
//do something...
}
To fix this, you must either do this:
struct foo{
int x;
foo(){};
};
or this:
typedef struct foo{
int x;
foo(){};
} foo;
Where the latter creates a struct called "foo" and gives it the alias "foo" so you don't have to use the struct keyword when referencing it.
As the other answers mention, a struct is basically treated as a class in C++. This allows you to have a constructor which can be used to initialize the struct with default values. Below, the constructor takes sz and b as arguments, and initializes the other variables to some default values.
struct blocknode
{
unsigned int bsize;
bool free;
unsigned char *bptr;
blocknode *next;
blocknode *prev;
blocknode(unsigned int sz, unsigned char *b, bool f = true,
blocknode *p = 0, blocknode *n = 0) :
bsize(sz), free(f), bptr(b), prev(p), next(n) {}
};
Usage:
unsigned char *bptr = new unsigned char[1024];
blocknode *fblock = new blocknode(1024, btpr);
Class, Structure and Union is described in below table in short.
Yes, but if you have your structure in a union then you cannot. It is the same as a class.
struct Example
{
unsigned int mTest;
Example()
{
}
};
Unions will not allow constructors in the structs. You can make a constructor on the union though. This question relates to non-trivial constructors in unions.
In c++ struct and c++ class have only one difference by default struct members are public and class members are private.
/*Here, C++ program constructor in struct*/
#include <iostream>
using namespace std;
struct hello
{
public: //by default also it is public
hello();
~hello();
};
hello::hello()
{
cout<<"calling constructor...!"<<endl;
}
hello::~hello()
{
cout<<"calling destructor...!"<<endl;
}
int main()
{
hello obj; //creating a hello obj, calling hello constructor and destructor
return 0;
}
Yes. A structure is just like a class, but defaults to public:, in the class definition and when inheriting:
struct Foo
{
int bar;
Foo(void) :
bar(0)
{
}
}
Considering your other question, I would suggest you read through some tutorials. They will answer your questions faster and more complete than we will.
Note that there is one interesting difference (at least with the MS C++ compiler):
If you have a plain vanilla struct like this
struct MyStruct {
int id;
double x;
double y;
} MYSTRUCT;
then somewhere else you might initialize an array of such objects like this:
MYSTRUCT _pointList[] = {
{ 1, 1.0, 1.0 },
{ 2, 1.0, 2.0 },
{ 3, 2.0, 1.0 }
};
however, as soon as you add a user-defined constructor to MyStruct such as the ones discussed above, you'd get an error like this:
'MyStruct' : Types with user defined constructors are not aggregate
<file and line> : error C2552: '_pointList' : non-aggregates cannot
be initialized with initializer list.
So that's at least one other difference between a struct and a class. This kind of initialization may not be good OO practice, but it appears all over the place in the legacy WinSDK c++ code that I support. Just so you know...
One more example but using this keyword when setting value in constructor:
#include <iostream>
using namespace std;
struct Node {
int value;
Node(int value) {
this->value = value;
}
void print()
{
cout << this->value << endl;
}
};
int main() {
Node n = Node(10);
n.print();
return 0;
}
Compiled with GCC 8.1.0.
struct HaveSome
{
int fun;
HaveSome()
{
fun = 69;
}
};
I'd rather initialize inside the constructor so I don't need to keep the order.
Syntax is as same as of class in C++. If you aware of creating constructor in c++ then it is same in struct.
struct Date
{
int day;
Date(int d)
{
day = d;
}
void printDay()
{
cout << "day " << day << endl;
}
};
Struct can have all things as class in c++. As earlier said difference is only that by default C++ member have private access but in struct it is public.But as per programming consideration Use the struct keyword for data-only structures. Use the class keyword for objects that have both data and functions.
Yes structures and classes in C++ are the same except that structures members are public by default whereas classes members are private by default. Anything you can do in a class you should be able to do in a structure.
struct Foo
{
Foo()
{
// Initialize Foo
}
};
Yes it possible to have constructor in structure here is one example:
#include<iostream.h>
struct a {
int x;
a(){x=100;}
};
int main() {
struct a a1;
getch();
}
In C++ both struct & class are equal except struct'sdefault member access specifier is public & class has private.
The reason for having struct in C++ is C++ is a superset of C and must have backward compatible with legacy C types.
For example if the language user tries to include some C header file legacy-c.h in his C++ code & it contains struct Test {int x,y};. Members of struct Test should be accessible as like C.
In C++, we can declare/define the structure just like class and have the constructors/destructors for the Structures and have variables/functions defined in it.
The only difference is the default scope of the variables/functions defined.
Other than the above difference, mostly you should be able to imitate the functionality of class using structs.