I'm working on a simple program for Boolean algebra, but the double negation does not work as expected.
I have the following classes:
Operator:
#ifndef OPERATOR_H
#define OPERATOR_H
class Operator {
public:
virtual int getArity(void) const = 0;
virtual bool calc(void) const = 0;
};
#endif // OPERATOR_H
False:
#ifndef FALSE_H
#define FALSE_H
#include "operator.h"
class False : public Operator {
public:
int getArity() const {
return 0;
}
bool calc(void) const {
return false;
}
};
#endif // FALSE_H
Not:
#ifndef NOT_H
#define NOT_H
#include "operator.h"
class Not : public Operator {
public:
Not(Operator& child) : m_child(child) {
std::cout << "not constructor called" << std::endl;
}
int getArity(void) const {
return 1;
}
bool calc(void) const {
return !m_child.calc();
}
private:
Operator& m_child;
};
#endif // NOT_H
My main.cpp:
#include <iostream>
#include "operator.h"
#include "not.h"
#include "false.h"
using namespace std;
int main(int argc, char *argv[]) {
False f;
Not n = Not(f);
Not d = Not(n);
cout << "n.calc(): " << n.calc() <<endl;
cout << "d.calc(): " << d.calc() <<endl;
return 0;
}
Since d = Not(Not(False())) I expect it to be false.
The output is:
not constructor called
n.calc(): 1
d.calc(): 1 <== should be 0
Why is the constructor of the class Not not called with an object of type Not as child?
Not d = Not(n); invokes the copy constructor of Not, because the argument is also of type Not. The copy constructor's signature matches better and it's therefore selected.
Static1.hpp
#include <string>
class Static1
{
public:
static const std::string my_string;
};
Static1.cpp
#include "Static1.hpp"
const std::string Static1::my_string = "aaa";
Static2.hpp
#include <string>
class Static2
{
public:
static const std::string my_string;
};
Static2.cpp
#include "Static2.hpp"
const std::string Static2::my_string = Static1::my_string;
main.cpp
#include "Static2.hpp"
#include <iostream>
int main(argc int, char** argv)
{
cout << to_string(Static2::my_string == "aaa") << endl;
return 0;
}
If I put add_executable(printMyString main.cpp Static2.cpp Static1.cpp) in my CMakeLists.txt, I get
0
while add_executable(printMyString main.cpp Static2.cpp Static1.cpp) gives me the expected behavior of
1
To make my code easier to maintain (so that I don't need to keep track of the order I list my source files), is there any way I can ensure that I get the behavior where Static2::my_string == "aaa"?
You are experiencing effects of a static initialization order fiasco.
The usual work-around is to substitute your static variables with functions that have a static variable in the scope, initialize, and return it.
Here is how it could be done for your example: Live Example (order1)
Live Example (order2)
class Static1
{
public:
static std::string my_string();
};
...
std::string Static1::my_string()
{
static const std::string my_string = "aaa";
return my_string;
}
...
class Static2
{
public:
static std::string my_string();
};
...
std::string Static2::my_string()
{
static const std::string my_string = Static1::my_string();
return my_string;
}
...
std::cout << std::to_string(Static2::my_string() == "aaa") << std::endl;
At the moment I am using a rather large piece of code to analyse data.
In this code apart from the analysis itself, I include some functions that will be used in the analysis, some function that are related to objects and some global variables. My code has the following structure
#include "header1.h"
#include "header2.h"
...
#define global_variable_1 1
#define global_variable_2 3
...
double function1(){
<code>
{
double function2(){
<code>
{
...
main(){
<code>
}
At the moment I want to make my code a bit more elegant, sophisticated and programmable correct. I am thinking of making a header file that will include the headers that I am using and some functions, a second header file with the rest of the functions and a last header file that will contain the global parameters that I use.
So I will have something like
#include "headers.h"
#include "functions.h"
#include "variables.h"
main(){
<code>
}
My question is whether it is programably proper to do so and if there is another and perhaps better way to include the global variables.
If you are trying to use variables that are global and you know that they are a constant value such as PI I would refrain from using both local globals and #define macros. This is a matter of preference but over time I've learned that it is better practice and more elegant to declare them as static const type name; in the header file and set the value accordingly in the cpp file. I also do not prefer to have a bunch of dangling values or basic methods hanging around so I usually will group similar types of values and methods and contain them in a class declaring them to be static. Here is an example:
Utility.h
#ifndef UTILITY_H
#define UTILITY_H
#include <iostream>
#include <string>
#include <stdio.h>
class Utility {
public:
static void pressAnyKeyToQuit();
static std::string& toUpper( std::string& str );
static std::string& toLower( std::string& str );
private:
Utility(); // Not Implemented - This class is not an object and can not be declared.
Utility( const Utility& c ); // Copy Constructor - Not Implemented
Utility& operator=( const Utility&c ); Assignment Operator - Not Implemented
}; // Utility
#endif // UTILITY_H
Utility.cpp
#include "Utility.h"
// -------------------------------------------------------------------------
// pressAnyKeyToQuit()
void Utility::pressAnyKeyToQuit() {
std::cout << "Press any key to quit" << std::endl;
_getch();
} // pressAnyKeyToQuit
// -------------------------------------------------------------------------
// toUpper()
std::string& Utility::toUper( std::string& str ) {
std::transform( str.begin(), str.end(), str.begin(), ::toupper );
return str;
} // toUpper
// -------------------------------------------------------------------------
// toLower()
std::string& Utility::toLower( std::string& str ) {
std::transform( str.begin(), str.end(), str.begin(), ::tolower );
return str;
} // toLower
To use these functions here is an example:
main.cpp
#include <iostream>
#include <string>
#include "Utility.h"
int main() {
std::string strHello( "Hello World!" );
std::cout << strHello << std::endl;
std::cout << Utility::toLower( strHello ) << std::endl;
std::cout << Utility::toUpper( strHello ) << std::endl;
Utility::pressAnyKeyToQuit();
return 0;
} // main
With this type of containment it is illegal to do this:
int main() {
Utility util;
util.pressAnyKeyToQuit();
} // main
This will fail because the Utility default constructor is private or inaccessible, however any type of function or variable that is declared as being static can be called through the scope resolution operator. Here is an example of const variables that would be considered globals.
GeneralMath.h
#ifndef GENERAL_MATH_H
#define GENERAL_MATH_H
class Math {
public:
static const float PI;
static const float PI_HAVLES;
static const float PI_2;
static const float ZERO;
inline static bool isZero( float fValue );
template<typename T>
inline static void swap( T& value1, T& value2 );
private:
Math();
Math( const Math& c ); // Not Implemented
Math& operator( const Math& c ); // Not Implemented
}; // Math
#include "GeneralMath.inl"
void dummy(); // does nothing used to have a method in the *.cpp file
#endif // GENERAL_MATH_H
GeneralMath.inl
// -------------------------------------------------------------------------
// isZero()
inline bool Math::isZero( float fValue ) {
if ( (fValue > -ZERO) && (fValue < ZERO) ) {
return true;
}
return false;
} // isZero
// -------------------------------------------------------------------------
// swap()
template<class T>
inline void Math::swap( T& value1, T& value2 ) {
T temp;
temp = value1;
value1 = value2;
value2 = temp;
} // swap
GeneralMath.cpp
#include "GeneralMath.h"
const float Math::PI = 4.0f * atan(1.0f); // tan(pi/4) = 1
const float Math::PI_HALVES = 0.5f * Math::PI;
const float Math::PI_2 = 2.0f * Math::PI;
const float Math::ZERO = static_cast<float>( 1e-7 );
void dummy(){return;}
Using it in an example:
main.cpp
#include <iostream>
#include "Utility.h"
#include "GeneralMath.h"
int main() {
float value = 3.14957;
if ( Math::isZero( value - Math::PI ) ) {
std::cout << "true" << std::endl;
} else {
std::cout << "false" << std::endl;
}
Utility::pressAnyKeyToQuit();
return 0;
} // main
I prefer this approach so that when common stand alone methods and constant variables are frequently used in multiple files and have a similar grouping you do not have a bunch of #defines or global's declared everywhere.
Now on the other hand if a specific class object that you are creating depends on a specific constant value that is unique to it then you can have a global in its *.h or *.cpp file but again I would still declare it as a static const type name;
The simplicity of this is to include the *.h file where it is needed and use the class name with the scope resolution operator followed by the const variable or static method where it is needed.
You can also do a similar approach without using a class and not declaring them as static by containing them in a namespace, but this could cause problems because other developers might have the same name space and this could create conflicts to resolve names. This is why I prefer the class approach and declaring them as static members.
Remember these classes are not Objects and they can not be constructed and all members have to be static!
I'm create my own LOGGER, where I use an additional class for overload macro.
There is #define qlcd MacroCall(QLC::Debug), so i can use logger like this: qlcd << message;
It's ok, but when i try use qlcd("log name") i got an error. Look minimal code (no macro for simplify):
#include <QVariant>
#include <QDebug>
class QLC
{
public:
// Error types
enum LevelType{
Debug=0, // Debug
Error=1, // Error
WTF = 2 // WTF???
} level;
QString logger;
// Constructors
QLC(QLC::LevelType l)
:level(l), logger(":")
{}
QLC(QLC::LevelType l, QString log)
:level(l), logger(log)
{}
// OPERATOR <<
QLC& operator<<(const QVariant var){
qDebug() << "(" + QString::number(level) + ")" << logger << var;
}
};
class MacroCall
{
QLC::LevelType level;
public:
MacroCall()
:level(QLC::Debug){}
MacroCall(int i)
:level(QLC::WTF){}
MacroCall(QLC::LevelType l)
:level(l){}
QLC operator()(){
return QLC(level);
}
QLC operator()(QString log){
return QLC(level, log);
}
};
int main(int argc, char*argv[])
{
MacroCall()("WorkLog") << "No level, yes logname";
MacroCall(QLC::Error)() << "No logname, yes level";
MacroCall a(QLC::Error);
a("WorkLog") << "Logname and level at different lines";
// GET READY!
// INT as level and logname:
MacroCall(2)("WorkLog") << "WTF?? It works!";
//MacroCall(QLC::WTF)("NotWorkLog") << "It's not work!!!!!!";
// NOT WORK: error: invalid use of qualified-name 'QLC::WTF'
// Qt 4.8.3
return 0;
}
The code
MacroCall(QLC::WTF)("NotWorkLog")
is interpreted as declaration of a variable:
MacroCall QLC::WTF("NotWorkLog")
Example:
class A
{
public:
enum E {
x=1
};
public:
A(E) {}
void operator()(int) const { }
};
class B {};
void f()
{
(A(A::x))(1); // Ok
A{A::x}(1); // Ok
A(a)(A::x); // Ok
A::E a; // ‘a’ has a previous declaration as ‘A a’
A(A::x)(1); // invalid use of qualified-name ‘A::x’
B(b)(A::x); // no matching function for call to ‘B::B(A::E)’
}
The code you gave compiles (except that the method QLC& operator<<(const QVariant var) has to return something), eventhough I'm not sure of how it's supposed to be used.
My guess is that your 2 classes are defined in different headers and an include is missing. Does Macrocall header include QLC header ?
Is it possible to know the object instance name / variable name from within a class method? For example:
#include <iostream>
using namespace std;
class Foo {
public:
void Print();
};
void Foo::Print() {
// what should be ????????? below ?
// cout << "Instance name = " << ?????????;
}
int main() {
Foo a, b;
a.Print();
b.Print();
return 0;
}
No. Variable names are for the programmer, the compiler sees addresses.
Other languages that provide meta-data/reflection about their program might provide this functionality, C++ isn't one of those languages.
Not with the language itself, but you could code something like:
#include <iostream>
#include <string>
class Foo
{
public:
Foo(const std::string& name) { m_name = name;}
void Print() { std::cout << "Instance name = " << m_name << std::endl; }
private:
std::string m_name;
};
int main()
{
Foo a("a");
Foo b("b");
a.Print();
b.Print();
return 0;
}
Variable names do not exist in the compiled code.
However you can use some #define to get the name in preprocessing and let the names be populated before the compile.
Something like this:
#define SHOW(a) std::cout << #a << ": " << (a) << std::endl
// ...
int i = 2;
SHOW (i);
What would that mean?
void f(T const& p) {
cout << p.name();
}
T r() {
T c;
return c;
}
void g() {
T a;
cout << a.name();
T & b = a;
cout << b.name();
T * ptr = &b;
cout << ptr->name();
T d = r();
cout << d.name();
}
What would you expect? "a" each time? And what about c/d?
Variable names don't survive compilation. The best you can do is to pass the variable name into the object constructor and store it inside the object by using a macro. The latter will lead to really ugly code so you would only want this as a last resort.
For the bounty:
This is one of the biggest and most disgusting hacks I've ever created but its good enough for debug reasons in my opinion
#include <iostream>
#include <typeinfo>
#define DEBUG_INSTANCE( classtype, name ) class _ ## classtype ## _INSTANCE_ ## name ## _ : public classtype \
{ \
public: \
_ ## classtype ## _INSTANCE_ ## name ## _ (){ } \
}; \
_ ## classtype ## _INSTANCE_ ## name ## _ name
class Foo {
public:
virtual void _MakeTypeIDRunTime() { }
// A virtual method in the class forces typeid(*this) to be used runtime rather than compiled
// See: https://stackoverflow.com/a/6747130/1924602
void Print();
};
void Foo::Print() {
std::cout << "Instance name = " << typeid(*this).name() << std::endl;
}
int main()
{
DEBUG_INSTANCE(Foo, a);
DEBUG_INSTANCE(Foo, b);
a.Print();
b.Print();
system("PAUSE");
return 0;
}
Output:
Instance name = ?AV_Foo_INSTANCE_a_#?1?main#
Instance name = ?AV_Foo_INSTANCE_b_#?1?main#
Press any key to continue . . .
This macro will create a class that inherits Foo and name contains the instance name. Only limitation is that Foo has a default constructor and must contain a virtual method in order for typeid to accept inherited classes and be called used at runtime. See https://stackoverflow.com/a/6747130/1924602 for a better explanation
Might be possible to support constructors if you use the __VA_ARGS__ macro
It is certainly possible for an instance to know its name from within the class method:
#include <iostream>
class Foo {
public:
void Print() { std::cout << "Instance name = " << this << std::endl; }
};
int main() {
Foo a, b;
a.Print();
b.Print();
return 0;
}
will produce the output similar to this:
Instance name = 0x7fff502b8b48
Instance name = 0x7fff502b8b40
As for knowing the variable name, it is certainly not possible. The existence of the object does not imply the existence of the variable - this instance:
new Foo();
will exist for the remaining duration of the process, yet will never be associated with any variable. The language concept of variables is not reflected in the contents of said variables, and any potential relation between language variable and an object is expressed only in the generated code and not in generated data or meta-data. Barring of course the access to the debug information which, as already pointed out, is not part of the language.
It is not possible with the language itself. However, you can use preprocessor to get it. But it is not going to be clear and you will have to be careful if your classes have different constructors. Also you will have to do it in each class.
I reuse the example of Steven Keith in combination with #define preprocessor:
#include <iostream>
#include <string>
using namespace std;
class Foo
{
public:
Foo(const string& name) : m_name(name) {}
void Print() { cout << "Instance name = " << m_name << endl; }
private:
string m_name;
};
#define DRESSED_Foo(var) Foo var(#var)
int main()
{
DRESSED_Foo(a);
DRESSED_Foo(b);
a.Print();
b.Print();
return 0;
}
The keyword this
I'm new to programming, but having studied class structure I believe what you might be looking for is the keyword this. As in the example below (taken from cplusplus.com), you can see that this is used anywhere the class needs to refer to itself.
Therefore, it is possible for a constructor to do this as well.
// example on this
#include <iostream>
using namespace std;
class Dummy {
public:
bool isitme (Dummy& param);
};
bool Dummy::isitme (Dummy& param)
{
if (¶m == this) return true;
else return false;
}
int main () {
Dummy a;
Dummy* b = &a;
if ( b->isitme(a) )
cout << "yes, &a is b\n";
return 0;
}
http://www.cplusplus.com/doc/tutorial/templates/
It is not possible. C++ does not have a concept of "reflection" like .NET platform.
But MFC library has CRunTime class - you can see for example.
Debug symbols do not exist as far as C++ is concerned. As a result, no C++ mechanism allows you to do anything with them.
Would it be possible to create platform-specific solution which would work? Possible. One would have to analyze the image of the process in memory, parse it according to specific format, figure out debug symbols (and frames) and map them to addresses. Essentially, debug itself.
Does it worth the trouble? Not in my opinion.
You can do it using #define. Define a macro which would save variable name inside class:
#include <iostream>
#include <string>
using namespace std;
#define CREATE_FOO(f) Foo f = Foo(#f);
class Foo {
public:
void Print() const;
Foo(string s): name(s) {};
protected:
string name;
};
void Foo::Print() const {
cout << "Instance name = " << name;
}
int main() {
CREATE_FOO(a);
CREATE_FOO(b);
a.Print();
b.Print();
return 0;
}
This is not possible "Directly", consider this simple program;
// stove.cpp
#include <string.h>
#include <stdio.h>
#include <iostream>
using namespace std;
class Foo {
char* t;
size_t length;
public:
Foo()
{
t = new char(8);
t = static_cast<char*>(static_cast<void*>(this));
}
void Print();
};
void Foo::Print() {
// what should be ????????? below ?
cout << this << " " << strlen (t) << t << endl;
}
int main() {
Foo a;
a.Print();
Foo b;
b.Print();
return 0;
}
you can check the value of t in gdb for both a and b objects,
1) run binary in gdb and put breakpoints on lines where both objects a and b gets created.
2) for both objects a and b , after creation (or in print function, check
print this
print t
18 }
(gdb) print this
$1 = (Foo * const) 0x7fffffffe6e0
(gdb) print t
$2 = 0x7fffffffe6e0 "\340\346\377\377\377\177"
...
...
...
30 Foo b;
(gdb) s
Foo::Foo (this=0x7fffffffe6d0) at stov.cpp:15
15 t = new char(8);
(gdb) n
16 t = static_cast<char*>(static_cast<void*>(this));
(gdb) n
18 }
(gdb) print this
$3 = (Foo * const) 0x7fffffffe6d0
(gdb) print t
$4 = 0x7fffffffe6d0 "\320\346\377\377\377\177"
class Food {
private:
uint8_t m_Temperature; // cooking temperature
public:
//constructor
Food (uint16_t Temperature) {
m_Temperature = Temperature;
}
//forward declaration
void CookIt(uint16_t NewTemperature);
}; // class
Food Burger(123);
Food Fries(233);
void Food::CookIt(uint16_t NewTemperature) {
Serial.print("I am cooking ");
if(this==&Burger) Serial.print("burger");
if(this==&Fries) Serial.print("fries");
Serial.print(" at ");
Serial.print(NewTemperature);
Serial.println(" Deg C");
Serial.println();
}