Strange code segment from c++ - c++

Reading code from other posts, I'm seeing something like this.
struct Foo {
Foo() : mem(0) {}
int mem;
};
What does mem(0) {} does in this case, especially regarding the curly brackets? I have never seen this before and have no idea where else I would find out about this. I know that mem(0), would intialize mem to 0, but why the {}?
Thanks.

Since Foo() is the class' constructor, it must have a body, even if the member variable mem is initialized outside of it.
That's why, in your example, the constructor has an empty body:
Foo() : mem(0)
{
// 'mem' is already initialized, but a body is still required.
}

It defines the constructor of the class. The part after the colon is the initialization list, in which the mem member is initialized to zero using a constructor call.
Compare:
int a(0);
int b = 0;
These two do the same, but the former is more in line with how object construction typically looks in C++.

int c++ you can define your method implementation in .h file
class MyClass
{
public:
MyClass(){
.....
}
void doSomething(){
.....
}
~MyClass(){
.....
}
};
Usually it used in templates implementation. Also you could use this method of class declaration in case you would like to avoid libraries linking and you prefer to give to user all your code so he can include your file without linking any lib file to his project.

Related

code organization in c++

I have a class that spans over two files. It is declared in a declare.h file and defined in define.cpp file.
define.h
class A{
public: int a;
void func(){ a = some_other_func(); }
A();
};
define.cpp
A::A(){
a =0;
}
The overall idea is to initialize a variable in constructor before using it in an inline function. But the constructor definition and function definition are in different files. Is there any issue with this?
There is absolutely no issue with the declaration/definition separation, provided declare.h is included in define.cpp. But the usulal practice is for implementation files to have the same name as declaration files, bar the suffix. So your case could be A.h and A.cpp.
However, there is an issue with the initialization of member variable a itself. You may want to initialize int a in the constructor initialization list:
A::A() : a(0) {}
In your code, it is not being initialized at all . You are creating and initializing a local variable called a a local variable in the body of the constructor. Presumably that is not what you intended.
You need to #include "declare.h" in define.cpp and then write constructor as A::A() : a(0){}.
Though in general this is no technical issue with this. You should adopt the convention that the .h files are interfaces to your code and as such they should only have what is needed for some other code to call yours.

nested class as a parameter for the member function in C++

I am integrating someone's code, which has everything in one cpp file. The main code is like this:
class Outer
{
public:
struct Inner
{
struct In_inner
{
...
}
}
int func(Inner& inn, Inner::In_inner& in_inn)
{
...
}
}
To make separation, should I add the "Outer::" for the "Inner" parameter, as follows?
in the header file
class Outer
{
public:
struct Inner
{
struct In_inner
{
...
}
}
int func(Inner& inn, Inner::In_inner& in_inn);
}
and in the cpp file:
int Outer::func(Outer::Inner& inn, Outer::Inner::In_inner& in_inn)
{
...
}
It sounds a bit weird to me that the parameter list is a bit different from the declaration. Also, can I keep everything in the same file again, and include it as a header file?
Thanks for any comments!
int Outer::func(Outer::Inner& inn, Outer::Inner::In_inner& in_inn)
Yes. You've correctly written this. You've to add Outer:: if you define it outside the class.
It sounds a bit weird to me that the parameter list is a bit different from the declaration
That is okay. The function is defined outside the class. You're no more in the scope of the class. Hence it looks a bit different.
But if you don't want it to look different, then you can write Outer:: in the declaration as well, as shown below:
class Outer
{
public:
//...
int func(Outer::Inner& inn, Outer::Inner::In_inner& in_inn);
};
This is fine, and would work because Outer is an injected-name, its available inside the class as well.
struct A
{
struct B {
struct C {};
};
B b1; //okay - as usual
A::B b2; //this is also okay - not so usual though
B::C c1; //okay - as usual
A::B::C c2; //this is also okay - not so usual though
A::A::A::A::A::A *pA; //this is very very unsual. But it is also okay!
};
The last line is okay, because the name A is injected inside the definition of class A. Hence it becomes recursively available.
See it compiles fine:
http://www.ideone.com/oiy2h
The parameter list isn't different; the types are the same. It's not uncommon to have explicitly qualified std:: members in the header file and use using namespace std; in the source file, either. That's basically the same thing.
It doesn't matter how you qualify the types, as long as they refer to the same types. And because you are not in the scope of Outer in the source file, the explicit qualification is necessary there.
Within the class declaration/definition, you are in the scope Outer::. Outside that (in your .cpp), you are not.
Yes, you can keep the function definition in the header: it is an implicit inline.

C++ - .h and .cpp

If I have a .h file that contains the following for example:
class A
{
...
}
Notice that there is no customized constructor here.
Now, in the .cpp file, can I write the following:
A
{
...
}
In other words, is it ok not to use a constructor after the class name as follows?
A::A()
{
...
}
Thanks.
If your question is whether or not you can use A{} to define a constructor, no, you need to use A::A(){...} syntax for the constructor if you are defining it in the cpp file.
If you are asking if you don't need a constructor, no, you don't necessarily need one, the compiler will supply you with a default.
I should say that if you are doing the constructor in the class definition you can use A(){...}, such as
class A
{
public:
A(){}
};
I believe the answer to your question is "No". But it's kind of a confusing question. The syntax you propose for the contents of the .cpp file is demonstrably uncompilable.
is it ok not to use a constructor after the class name
As classes get longer and more complicated, mixing the definition and the implementation details makes the class harder to manage and work with.
Traditionally, the class definition is put in a header file of the same name as the class, and the member functions defined outside of the class are put in a .cpp file of the same name as the class.
No. Once you've defined class A like that, the compiler expects A to start one of
A MyObject;
A MyOtherObject = { /* initial values */ }; // C style since there's no ctor
A MyFunction();
A MyFunction() { return MyObject; }
or perhaps a variation like
A* MyPointer;
A& MyReferemce = MyObject;
As you see, the compiler expects you declare something after A. But you have A {. That's just not right: you started a declaration, but you never named what you're declaring.
Yes You Can.If i understood your question correctly.
HEADER FILE
#include &lt iostream&gt
using namespace std;
class A{
public:
A();
void func();
};
CPP FILE
#include "h.hpp"
using namespace std;
A::A(){cout &lt&lt "Constructor" &lt&lt endl;}
int main(){
A a;
return 0;
}

Passing member function to function pointer

I have to pass in a function pointer of a member function to another class. I couldn't get it to compile and I get the "undefined reference to classB::classB(classA::*)(std::shared_ptr) " error. Can someone help me with this?
Thanks.
classA{
string functionA(share_ptr<int>);
void functionB(){
classB* ptr = new classB(&classA::functionA);
}
}
//in other .h file
classA; //forward declaration
classB{
classB(string (classA::*funcPtr)(shared_ptr<int>); //constructor
}
Your code as I'm writing this:
classA{
string functionA(share_ptr<int>);
void functionB(){
classB* ptr = new classB(&classA::functionA);
}
}
Here:
share_ptr should be shared_ptr.
There is a missing semicolon at the end of the class definition.
Then,
//in other .h file
classA; //forward declaration
classB{
classB(string (classA::*funcPtr)(shared_ptr<int>); //constructor
}
Here:
There are three left parentheses ( but only two right parentheses ).
A semicolon is missing at the end of the class definition.
You're asking about a linking error, but your code should not even compile.
When you state "I couldn't get it to compile" that seems to be correct.
When you then state "I get [undefined reference to...]", well that's a mystery: with the toolchain that you're evidently using, the linker shouldn't be invoked when the compilation fails.
In summary, this question contains some incorrect information and any answer (such as the hypothesis that you haven't defined the function, or the hypothesis that you defined it somewhere but forgot to link in that, or the hypothesis that you're reporting errors from building something else than your code, so on) would be pure guesswork.
Please post a complete small program that compiles and illustrates the linking error.
Cheers & hth.,
Just for giggles, going to answer this even though you said it compiled for you ...
// In a.hpp
#include "b.hpp" // you need to include this because you will not
// be able to call B's constructor in your functionB() method
class A
{
public:
string functionA ( shared_ptr<int> ); // IIRC, needs to be public to call it
// from B's constructor.
// can be public/protected/private depending on where it's called ...
void functionB () {
B * ptrB = new B ( &A::functionA );
}
};
and
// In b.hpp
// Forward declare class A
class A;
// To make the constructor of B cleaner, use a typedef.
typedef string (A::*IntPtrToStrFn) ( shared_ptr<int> );
class B
{
public:
B ( IntPtrToStrFn fnptr );
};
As far as style and code readability goes, this is horrible - ties the two classes together and reaks of code smell. Need to look at some kind of adapter class or other design pattern to get the two classes to work together.
On the surface, this just looks like a forward declaration issue. Try declaring classA::functionB as you've done, and then defining classA::functionB after the definition of classB.

Static Variables, Separate Compilation

I wrote a program out, which was all in one file, and the methods were forward declared in a header. The program initially worked perfectly when it was in one file. But when I separated the program, I kept getting random occurrences for the destructor of one of the classes which was declared in the header file.
I have a static variable in my header to count the number of objects of a particular class. Whenever I construct the object I increment this variable. Then in my destructor I subtract 1 from that variable, check if it's 0 (meaning it's the last object) and do something. The value seems to be off sometimes, I'm not sure why. I do have random calls in my application but I don't see why that would effect what I have described above, thanks. Any help or insight is appreciated!
[Update]: have a base class, which contains the destructor.. which is implemented in the header, then I have two derived classes, which in their constructor increment the static var.. so what can I do?
What I am trying to do is the following: In my header I have this:
class A {
public:
virtual ~A() {
count --;
if (count == 0) { /* this is the last one, do something */ }
}
class B : public A {
public:
B();
}
Then in Class B I have
B::B() {
count++;
}
Where can I define count so I don't get misleading counts? Thanks.
You must define the constructor in A (all of them) to increment the count.
Note unless you define them the compiler automatically generate the following four methods:
Default Constructor (if no other constructor is defined)
Default Destructor
Copy Constructor
Assignment operator
The following code overrides the compiler defaults so that you should get an accurate count.
class A
{
static int count;
public:
A() // Default constructor.
{
++count;
}
A(A const& copy) // Copy constructor/
{ // Note If you do not define it the compiler
++count; // will automatically do it for you
}
virtual ~A()
{
--count;
if (count == 0)
{ // PLOP
}
}
// A& operator=(A const& copy)
// do not need to override this as object has
// already been created and accounted for.
};
////
In source file:
int A::count = 0;
Where is your static variable defined? Perhaps you are accidentally defining it in the header file, and the inlining is confusing things (and the compiler doesn't catch the multiple definitions, which would be odd, but you never know).
Make sure a class-static variable is defined in exactly one translation unit. You define it like this:
int MyClass::static_var;
This is also the place you put the initializer, if any.
class A {
public:
virtual ~A() {
count --;
if (count == 0) { // this is the last one, do something }
}
protected:
static int count;
};
class B : public A{
public:
B();
};
And then, in one and only one of your source files you need to put the following. It should go in the source file that contains the code for class A.
int A::count(0);
You need to do this, because the header file declared that there was going to be a variable named count, but didn't allocate any storage for it. If you didn't put it in a source file, the linker would complain that it wasn't found.
Can you elaborate what you mean by the "value seems to be off"? Do you get too many constructions? Not enough destructions? If you get too many constructions and not enough destructions, it would not have anything to do with the statics.
Also, what do you mean by a static variable? Do you mean a static member field or an actual static variable ?
If you declare just a static variable in the header (which I doubt that you do), then each C file that includes that header would have a separate instance of that variable (since static before a global variable means that it is limited to that object file).