Global pointer to object causes access violation? - c++

Maybe you will be able to clear something for me, because I don't know exactly where my thinking is flawed. First some code:
Talker.h:
class talker
{
public:
talker();
void sayHello() {cout << "Hello";} ;
};
anotherClass.h:
class anotherClass
{
public:
anotherClass();
void doSomethingYourself() { cout << "will do"; };
void askHimToSayHello() { pointerToTalker->sayHello; };
//Access violation, bad pointer(?)
};
common.h:
static talker *pointerToTalker;
// if I add here "= new talker", code works fine
main.cpp:
#include "common.h"
int main()
{
pointerToTalker = new talker; // Here is the bug, but why?
pointerToTalker -> sayHello; // says Hello alright
anotherClass *pointerToAnotherClass = new anotherClass;
pointerToAnotherClass -> doSomething (); //Does something OK
pointerToAnotherClass -> askHimToSayHello(); // Causes access violation
}
Of course functions are a bit more complex, and each is implemeted in coresponding .cpp including "common.h". My question is - why pointerToTalker, if initialized inside main() does not work inside anotherClass::AskHimToSayHello()? It should pointing to valid memory by the time it is used there.
It is my "Hello world, OOP!" btw, so please be gentle if there is no hope for me :)
Sorry for the childish style btw. It helps me cut down the code I have to something more compact without me loosing the big picture :).

Because
static talker *pointerToTalker;
is not a global. In this context, static gives the variable internal linkage for each translation unit (cpp file + included files) in which common.h is included.
You need to declare it as extern:
extern talker *pointerToTalker;
and initialize it in a single implementation file.
Declaring it static will create a copy of pointerToTalker for each translation unit. So you're initializing the one from main.cpp. Others are left uninitialized, and thus you run into undefined behavior. The proper way is:
//common.h:
extern talker *pointerToTalker;
//common.cpp
#include "common.h"
talker* pointerToTalker = new talker;

Related

C++ - how to forward declare a class in the same file as main() - getting variable uses undefined class error

I'm aware of using function prototypes, and I was under the impression that forward class declarations could serve a similar purpose when main() and a class are in the same file. For example, I would have expected this would compile:
// main.cpp
#include <iostream>
// class prototypes
class MyClass;
int main(void)
{
MyClass myClass;
// do stuff with myClass here
return(0);
}
class MyClass
{
public:
int someInt;
double someDouble;
// more stuff here . . .
};
But on the MyClass myClass; line I'm getting the error 'myClass' uses undefined class 'MyClass'. What am I doing wrong?
P.S. I'm aware that I could cut/paste main() below all the classes it uses and that would fix the error, but I'd prefer to keep main() as the first function or class.
P.P.S. I'm aware that in any substantial size production program main(), .h content, and .cpp content would be in 3 separate files. In this case I'm attempting to write a small example or test program where main and a class(es) are in the same file.
Forward declarations can only be used via pointers or references.
Calling a constructor function doesn't fall into this category.
I'm aware that I could cut/paste main() below all the classes it uses and that would fix the error, but I'd prefer to keep main() as the first function or class.
That's why usually header files are used, instead of placing all the declarations and definitions in the main.cpp file.
I'm aware that in any substantial size production program main(), .h content, and .cpp content would be in 3 separate files. In this case I'm attempting to write a small example or test program where main and a class(es) are in the same file.
You should still stick to that idiom though, everything else would probably end up in a mess.
This doesn't use forward declarations but it partially addresses the spirit of a single main.cpp with your "main" at the top. I find this technique sometimes useful when you want to share something via an online C++ ide where a single file is much easier to deal with, and you want to focus on the action in main rather than implementation detail in helper structs/classes etc.
#include <iostream>
template<typename MyClass,typename MyOtherClass>
int main_()
{
MyClass a;
a.do_foo();
MyOtherClass b;
b.do_bar();
return 0;
}
struct MyClass
{
void do_foo() { std::cout << "MyClass: do_foo called\n"; }
};
struct MyOtherClass
{
void do_bar() { std::cout << "MyOtherClass: do_bar called\n"; }
};
int main()
{
return main_<MyClass,MyOtherClass>();
}

Should this function be static?

I just got a sample of code, which cannot be modified:
#include <iostream>
#include "Image.h"
#include "Ppm.h"
int main() {
Image* ob = 0x0;
try
{
ob = new Ppm("lena.ppm");
long kolor = countColors(*ob);
std::cout << "Unikalnych kolorow: " << kolor << '\n';
}
catch (ImageError& e)
{
std::cout << e.what() << std::endl;
}
delete ob;
return 0;
}
I am confused with line
long kolor = countColors(*ob);
Two questions:
1) should this function be static?
2) should it be in class Image, or in Ppm, which inherit from the first one?
I am confused with line
long kolor = countColors(*ob);
You say that the code cannot be modified, so this line is already there in the code, and I assume the code is compiling/linking OK?
If it compiles OK, the function declaration for countColors() must be getting included from either from Image.h or Ppm.h, or from a header file that one of them includes. It certainly isn't coming from iostream.
If it's linking successfully, the object file or library containing the function definition for countColors() must be getting included in the link step.
We can only guess at the signature of this function; something like:
long countColors(const Ppm& portablePixmap);
...or maybe...
long countColors(const Image& image);
Whatever the signature is, it would not be declared with the keyword static (outside of a class), unless it was only used in the same file it's implemented in.
1) should this function be static?
The short answer is: it's unlikely that it is declared as static (see why below), but that's probably not what you're really asking about.
We know countColors() isn't a class method or instance method, because if it were, you'd have to call it like this1:
long kolor = SomeClass::countColors(*ob); // (class method)
or
long kolor = some_instance.countColors(*ob); // (instance method)
So if it's not a class or instance method, is it static? Probably not; here's why:
Say you've defined a function foo in file foo.c:
void foo(void) { ... }
...you can call it from bar.c:
#include "foo.h" // Tells compiler about foo()
void bar() { foo(); } // COMPILES AND LINKS OK
...but if you had defined the function in foo.c using the static keyword:
static void foo(void) { ... }
...the linker treats it as private to foo.c, so you can't call it from bar.c or any other source file besides foo.c:
#include "foo.h" // Tells compiler about foo()
void bar() { foo(); } // COMPILE OK, BUT LINKER ERROR!
2) should it be in class Image, or in Ppm, which inherit from the first one?
'should' implies that you're looking for the right place to put this method, but you also stated that this code can't be modified.
Are you trying to call this method from your own code, and you're not sure which header file to include, or how to call it?
Sorry, I could give you a better answer if I understood what it was you wanted to do.
1 It's possible to do evil things with macros in C/C++ like #define countColors(x) SomeClass::countColors(x), but we'll ignore that possibility.

Classes included within main() method

If I have some code like
main(int argc, char *argv[])
{
...
#include "Class1.H"
#include "Class2.H"
...
}
Generally the main() method is the starting point of every application and the content within main() is to be executed. Am I right in the assumption that the content of all classes included into main() will be executed when main() is started?
greetings
Streight
No, no, NO.
First of all, you don't #include a file within a function. You #include a file at the beginning of a file, before other declarations. OK, you can use #include anywhere, but you really just shouldn't.
Second, #include doesn't execute anything. It's basically just a copy-paste operation. The contents of the #included file are (effectively) inserted exactly where you put the #include.
Third, if you're going to learn to program in C++, please consider picking up one of our recommended texts.
You commented:
I am working with the multiphaseEulerFoam Solver in OpenFoam and
inside the main() of multiphaseEulerFoam.C are classes included. I
assume that the classes have the right structure to be called in
main()
That may be the case, and I don't doubt that the classes have the right structure to be called from main. The problem is main will be malformed after the #includes because you'll have local class definitions and who knows what else within main.
Consider this. If you have a header:
foo.h
#ifndef FOO_H
#define FOO_H
class Foo
{
public:
Foo (const std::string& val)
:
mVal (val)
{
}
private:
std::string mVal;
};
#endif
And you try to include this in main:
main.cpp
int main()
{
#include "foo.h"
}
After preprocessing the #include directive, the resulting file that the compiler will try to compile will look like this:
preprocessed main.cpp
int main()
{
#ifndef FOO_H
#define FOO_H
class Foo
{
public:
Foo (const std::string& val)
:
mVal (val)
{
}
private:
std::string mVal;
};
#endif
}
This is all kinds of wrong. One, you can't declare local classes like this. Two, Foo won't be "executed", as you seem to assume.
main.cpp should look like this instead:
#include "foo.h"
int main()
{
}
#define and #include are just textual operations that take place during the 'preprocessing' phase of compilation, which is technically an optional phase. So you can mix and match them in all sorts of ways and as long as your preprocessor syntax is correct it will work.
However if you do redefine macros with #undef your code will be hard to follow because the same text could have different meanings in different places in the code.
For custom types typedef is much preferred where possible because you can still benefit from the type checking mechanism of the compiler and it is less error-prone because it is much less likely than #define macros to have unexpected side-effects on surrounding code.
Jim Blacklers Answer # #include inside the main () function
Try to avoid code like this. #include directive inserts contents of the file in its place.
You can simulate the result of your code by copy-pasting file content from Class1.H and Class2.H inside the main function.
Includes do not belong into any function or class method body, this is not a good idea to do.
No code will be executed unless you instantiate one of your classes in your header files.
Code is executed when:
Class is instantiated, then it's constructor method is called and the code inside the method is executed.
If there are variables of a class type inside your instantiated class, they will too run their constructors.
When you call a class method.
Try this example:
#include <iostream>
using namespace std;
int main()
{
class A
{ public:
A() { cout << "A constructor called" << endl; }
};
// A has no instances
class B
{ public:
B() { cout << "B constructor called" << endl; }
void test() { cout << "B test called" << endl; }
} bbb;
// bbb will be new class instance of B
bbb.test(); // example call of test method of bbb instance
B ccc; // another class instance of B
ccc.test(); // another call, this time of ccc instance
}
When you run it, you'll observe that:
there will be no instance of class A created. Nothing will be run from class A.
if you intantiate bbb and ccc, their constructors will be run. To run any other code you must first make a method, for example test and then call it.
This is an openFoam syntax he is correct in saying that open Foam treats #include like calling a function. In OpenFoam using #include Foo.H would run through the code not the class declaration that is done in a different hierarchy level. I would recommend all openFoam related question not be asked in a C++ forum because there is so much stuff built onto C++ in openFoam a lot the rules need to be broken to produce a working code.
You're only including declarations of classes. To execute their code, you need to create class instances (objects).
Also, you shouldn't write #include inside a function or a class method. More often than not it won't compile.

Is it possible to avoid repeating the class name in the implementation file?

Is there a way to avoid the Graph:: repetition in the implementation file, yet still split the class into header + implementation? Such as in:
Header File:
#ifndef Graph_H
#define Graph_H
class Graph {
public:
Graph(int n);
void printGraph();
void addEdge();
void removeEdge();
};
#endif
Implementation File:
Graph::Graph(int n){}
void Graph::printGraph(){}
void Graph::addEdge(){}
void Graph::removeEdge(){}
I'm guessing this is to avoid lots of "unnecessary typing". Sadly there's no way to get rid of the scope (as many other answers have told you) however what I do personally is get the class defined with all my function prototypes in nice rows, then copy/paste into the implementation file then ctrl-c your ClassName:: on the clip board and run up the line with ctrl-v.
If you want to avoid typing the "Graph::" in front of the printGraph, addEdge etc., then the answer is "no", unfortunately. The "partial class" feature similar to C# is not accessible in C++ and the name of any class (like "Graph") is not a namespace, it's a scope.
No there's not. Not directly at least. You could go for preprocessor tricks, but don't do it.
#define IMPL Graph::
IMPL Graph(int n){}
void IMPL printGraph(){}
void IMPL addEdge(){}
void IMPL removeEdge(){}
Also, you shouldn't even want to do it. What's the point. Besides it being a C++ rule, it lets you know you're actually implementing a member function.
One option is using. If you have method definitions which are in a cpp file that never gets #included, then using is safe (doesn't affect other files):
foo.h:
class FooLongNameSpecialisationsParamaters
{
int x_;
public:
int Get () const;
void Set (int);
};
foo.cpp:
#include "foo.h"
using Foo = FooLongNameSpecialisationsParamaters;
int Foo::Get () const
{
return x_;
}
void Foo::Set (int x)
{
x_ = x;
}
main.cpp:
#include "foo.h"
int main ()
{
//Foo foo; <-- error
FooLongNameSpecialisationsParamaters foo;
return 0;
}
No, there is no way to avoid it. Otherwise, how would you know if a given function definition is for a class function or for a static function?
If you are asking if you can define a member function such as Graph::printGraph without specifying the class name qualification, then the answer is no, not the way that you want. This is not possible in C++:
implementation file:
void printEdge(){};
The above will compile just fine, but it won't do what you want. It won't define the member function by the same name within the Graph class. Rather, it will declare and define a new free function called printEdge.
This is good and proper, if by your point of view a bit of a pain, because you just might want two functions with the same name but in different scopes. Consider:
// Header File
class A
{
void foo();
};
class B
{
void foo();
};
void foo();
// Implementation File
void foo()
{
}
Which scope should the definition apply to? C++ does not restrict you from having different functions with the same names in different scopes, so you have to tell the compiler what function you're defining.
//yes it is possible using preprocessor like this:
#define $ ClassName //in .cpp
void $::Method1()
{
}
//or like this: in the header .h:
#undef $
#define $ ClassName'
// but you have to include the class header in last #include in your .cpp:
#include "truc.h"
#include "bidule.h" ...
#include "classname.h"
void $::Method() { }
//i was using also
#define $$ BaseClass
//with single inheritance than i can do this:
void $::Method()
{
$$::Method(); //call base class method
}
//but with a typedef defined into class like this it's better to do this:
class Derived : Base
{
typedef Base $$;
}
EDIT: I misread your question. This would be an answer to the question whether you can split header-files. It doesn't help you to avoid using LongClassName::-syntaxes, sorry.
The simple answer: You can split up c++-file, but you can not split up header-files.
The reason is quite simple. Whenever your compiler needs to compile a constructor, it needs to know exactly how many memory it needs to allocate for such an object.
For example:
class Foo {
double bar; //8 bytes
int goo; //4 bytes
}
new Foo() would require the allocation of 12 bytes memory. But if you were allowed to extend your class definitions over multiple files, and hence split header files, you could easily make a mess of this. Your compiler would never know if you already told it everything about the class, or whether you did not. Different places in your code could have different definitions of your class, leading to either segmentation faults or cryptic compiler errors.
For example:
h1.h:
class Foo {
double bar; // 8 bytes
int goo; // 4 bytes
}
h2.h:
#include "h1.h"
class Foo {
double goo; // 8 bytes
} // we extend foo with a double.
foo1.cpp:
#include "foo1.h"
Foo *makeFoo() {
return new Foo();
}
foo2.cpp:
#include "foo2.h"
void cleanupFoo(Foo *foo) {
delete foo;
}
foo1.h:
#include "h1.h"
Foo *makeFoo();
foo2.h:
#include "h1.h"
#include "h2.h"
void cleanupFoo(Foo *foo)
main.cpp:
#include foo1.h
#include foo2.h
void main() {
Foo *foo = makeFoo();
cleanupFoo(foo);
}
Carefully check what happens if you first compile main.cpp to main.o, then foo1.cpp to foo1.o and foo2.cpp to foo2.o, and finally link all of them together. This should compile, but the makeFoo() allocates something else then the cleanupFoo() deallocated.
So there you have it, feel free to split .cpp-files, but don't split up classes over header files.

What if the default parameter value is defined in code not visible at the call site?

I've found some strange code...
//in file ClassA.h:
class ClassA {
public:
void Enable( bool enable );
};
//in file ClassA.cpp
#include <ClassA.h>
void ClassA::Enable( bool enable = true )
{
//implementation is irrelevant
}
//in Consumer.cpp
#include <ClassA.h>
....
ClassA classA;
classA.Enable( true );
Obviously since Consumer.cpp only included ClassA.h and not ClassA.cpp the compiler will not be able to see that the parameter has a default value.
When would the declared default value of ClassA::Enable in the signature of the method implementation have any effect? Would this only happen when the method is called from within files that include the ClassA.cpp?
Default values are just a compile time thing. There's no such thing as default value in compiled code (no metadata or things like that). It's basically a compiler replacement for "if you don't write anything, I'll specify that for you." So, if the compiler can't see the default value, it assumes there's not one.
Demo:
// test.h
class Test { public: int testing(int input); };
// main.cpp
#include <iostream>
// removing the default value here will cause an error in the call in `main`:
class Test { public: int testing(int input = 42); };
int f();
int main() {
Test t;
std::cout << t.testing() // 42
<< " " << f() // 1000
<< std::endl;
return 0;
}
// test.cpp
#include "test.h"
int Test::testing(int input = 1000) { return input; }
int f() { Test t; return t.testing(); }
Test:
g++ main.cpp test.cpp
./a.out
Let me admit first that this is the first time I have seen this type of code. Putting a default value in header file IS the normal practice but this isn't.
My guess is that this default value can only be used from code written in the same file and this way the programmer who wrote this wanted to put it in some type of easiness in calling the function but he didn't want to disturb the interface (the header file) visible to the outside world.
Would this only happen when the method
is called from within files that
include the ClassA.cpp?
That's correct. But note that doing so will almost certainly produce multiple definition errors, so the default is only really available from its point of definition within ClassA.cpp.
Put the default value in the declaration, not the definition.
class ClassA {
public:
void Enable( bool enable = true );
};