Got very weird problem...
I have variable:
Application *ApplicationHandle = NULL;
in Application's function I do:
ApplicationHandle = this;
And ApplicationHandle still remains as NULL... i'm checking this with debugger, before this operation ApplicationHandle is NULL, and 'this' got some address, I can see variables of this class that are valid. After operation ApplicationHandle should be the same pointer as this, but it is still NULL.
How is that possible?
I would suggest moving the static variable out of the global namespace and into the class as a static class member. Here is an example:
// test.hpp
#ifndef TEST_HPP
#define TEST_HPP
class Test
{
public:
// Constructor: Assign this to TestPointer
Test(void) { TestPointer = this; }
// This is just a definition
static Test* TestPointer;
private:
unsigned m_unNormalMemberVariable;
};
#endif /* #ifndef TEST_HPP */
The above code will not work by itself, you need to declare the actual memory of the static member variable (just like you would for a member function).
// test.cpp
#include "test.hpp"
#include <iostream>
// The actual pointer is declared here
Test* Test::TestPointer = NULL;
int main(int argc, char** argv)
{
Test myTest;
std::cout << "Created Test Instance" << std::endl;
std::cout << "myTest Pointer: " << &myTest << std::endl;
std::cout << "Static Member: " << Test::TestPointer << std::endl;
Test myTest2;
std::cout << "Created Second Test Instance" << std::endl;
std::cout << "myTest2 Pointer: " << &myTest2 << std::endl;
std::cout << "Static Member: " << Test::TestPointer << std::endl;
return 0;
}
The static member can be access from any file, not just the file containing the line Test* Test::TestPointer = NULL;. To access the contents of the static pointer, use Test::TestPointer.
Related
How to properly access the string "bye" from the struct?
#include <iostream>
static constexpr char hi[] = "hi";
struct S{ static constexpr char bye[] = "bye"; };
int main(int argc, char *argv[]) {
typedef struct S ST;
std::cout << hi << std::endl; // this prints "hi"
std::cout << sizeof(ST::bye) << std::endl; // this correctly prints 4
std::cout << ST::bye << std::endl; // this does not compile with "undefined reference"
}
I'm working with a c++ framework that has some configuration in this format (in multiply nested structs even) to make its values available during compile time. I'm not deep enough into C++ to grasp the underlying issue here. Also I cannot argue about why this approach on implementing the configuration was chosen and cannot change it.
This can be made working by redefining the static constexpr outside the struct:
#include <iostream>
static constexpr char hi[] = "hi";
struct S{ static constexpr char bye[] = "bye"; };
constexpr char S::bye[]; // <<< this line was missing
int main(int argc, char *argv[]) {
typedef struct S ST;
std::cout << hi << std::endl; // this prints "hi"
std::cout << sizeof(ST::bye) << std::endl; // this correctly prints 4
std::cout << ST::bye << std::endl; // Now this prints "bye"
}
Or by compiling using c++17 which makes this obsolete.
Related links:
constexpr static member before/after C++17
What does it mean to "ODR-use" something?
I already knew that value of pointer member of class is undefined if it is not initialized in constructor (refer this question). I made a simple example to test it.
main.cc
#include <iostream>
class Foo {
public:
Foo() {
std::cout << __FUNCTION__ << std::endl;
count = 10;
}
void test() {
std::cout << __FUNCTION__ << count << std::endl;
}
private:
int count;
};
class Bar {
public:
void bar() {
std::cout << __FUNCTION__ << std::endl;
std::cout << m_foo << std::endl;
m_foo->test();
m_foo = new Foo();
std::cout << m_foo << std::endl;
}
private:
Foo *m_foo;
};
int main(int argc, char *argv[])
{
std::cout << __FUNCTION__ << std::endl;
Bar bar;
bar.bar();
return 0;
}
If I use g++:
g++ -std=c++11 main.cc -o test
It runs with error as expected:
main
bar
0
Segmentation fault
But, if I change to compile with clang++:
clang++ -std=c++11 main.cc -o test
It runs without any error:
main
bar
0x400920
test-1991643855
Foo
0x1bf6030
As you see, although the pointer is not initialized, it has address not NULL and it can call the function test normally. How can I prevent this error with clang++?
There is no "default value" for pointers. m_foo is not initialized, period. So dereferencing it is undefined behaviour. Be aware that "undefined behaviour" includes "apparently working fine".
Declare m_foo like this:
Foo * m_foo = nullptr;
Dereferencing a nullptr is still undefined behaviour, but on most platforms this will trigger a segmentation fault.
I have 5 files. (1. A.hpp, A.cpp : 2. B.hpp, B.cpp : 3 main.cpp)
// A.hpp
#ifndef MY_CLASS_A
#define MY_CLASS_A
#include <iostream>
class B; // forward declaration so that I could do B * b;
struct s {
int x;
double y;
};
class A{
s my_struct;
int size;
B * b;
public:
A(int, double, int);
void f1(s);
void f2(); // this function calls B's f1 function
s get_struct();
int get_size();
void print();
};
#endif
Then I have its implementation as
// A.cpp
#include "A.hpp"
#include "B.hpp"
A::A(int x_, double y_, int size_):my_struct({x_, y_}), size(size_){}
void A::f1(s s_){
// do stuff
s_.x = 5;
s_.y = 51.99;
}
void A::f2(){
int val;
// Here I am calling B's f1 function
val = b->f1(my_struct);
}
s A::get_struct(){
return my_struct;
}
int A::get_size(){
return size;
}
void A::print(){
std::cout << " ----- " << std::endl;
std::cout << "x = " << my_struct.x << std::endl;
std::cout << "y = " << my_struct.y << std::endl;
std::cout << "size = " << size << std::endl;
std::cout << " ----- " << std::endl;
}
Then I have B
//B.hpp
#ifndef MY_CLASS_B
#define MY_CASS_B
#include "A.hpp" // I placed here A.hpp because I am
// trying to use A's struct type
class A;
class B{
public:
int f1(s); // A's struct use here to get struct by value
};
#endif
and its implementation as
// B.cpp
#include "B.hpp"
// used A's struct here again
int B::f1(s my_struct){
std::cout << "*****" << std::endl;
std::cout << my_struct.x << std::endl;
std::cout << my_struct.y << std::endl;
std::cout << "*****" << std::endl;
}
finally main as
// main.cpp
// As per comment I should place #include "A.hpp" here
#include "A.cpp"
int main(){
A a(4,9.9, 5);
a.print();
return 0;
}
My main question is how can I access the struct declared in class A into class B?
I have tried to use forward declaration by failed miserably.
Open your C++ book to the chapter on pointers and references, and read that chapter again.
"The struct declared in class A" is my_struct, which is a private class member.
To have it accessible elsewhere, you need to pass it by reference.
int B::f1(const s &my_struct){
std::cout << "*****" << std::endl;
std::cout << my_struct.x << std::endl;
std::cout << my_struct.y << std::endl;
std::cout << "*****" << std::endl;
}
Now, when you invoke this from A:
val = b->f1(my_struct);
This will now pass a reference to the my_struct member, instead of making a copy of it.
Note that the parameter is declared as a reference to a const instance of s, because f1() does not need to modify it. If it does, simply pass it as a non-const reference:
int B::f1(s &my_struct){
Now, f1() will be able to modify my_struct, and end up modifying this private instance of A's class, that was passed to it.
P.S. This has nothing to do with different translation units. Whether this whole thing is in one translation unit, or is split across half a dozen of them, classes and references work the same way.
In this program I just want to test a structure and union within a class itself.
I had created a public struct, and declared a union within it.
I am using Visual Studio and Qt Creator to type this code.
I want to ask, is defining a struct within a class good and accessible?
I am having problem with that.
If this is correct, how could I access the method or data member of the struct from main?
I'd also like to use the union member of the struct.
If the method or functions of the struct are not accessible this way,. what's another way of doing it?
//************************************************************************************
#ifndef CTEST_H
#define CTEST_H
class CTest {
int value;
public:
CTest(int);
int getValue();
struct CTESTSTRUCT {
union CTESTUNION
{
enum CTestEnum {
var1 = 1
};
char varChar1 = 'Y';
char varChar2 /*= 'N'*/; //union atmost have one field initializer
};
int structValue();
int testVal;
};
~CTest();
};
#endif
//************************************************************************************
#include <iostream>
#include "CTest.h"
CTest::CTest(int argVal) : value(argVal) {
std::cout << "Constructor Called" << std::endl;
}
int CTest::getValue() {
std::cout << "getValue Called" << std::endl;
return value;
}
int CTest::CTESTSTRUCT::structValue() {
std::cout << "CTESTSTRUCT::setValue Called" << std::endl;
return CTESTSTRUCT::CTESTUNION::var1;
}
CTest::~CTest() {
std::cout << "Distructor Called" << std::endl;
}
//*********************************************************************************
#include <iostream>
#include "CTest.h"
using namespace std;
CTest * ctestObj;
int main() {
ctestObj = new CTest(25);
int returnVal = ctestObj->getValue();
std::cout << "Value Returned: " << returnVal << std::endl;
std::cout << "structVal: " << std::endl;
//CTest::CTESTSTRUCT::testVal = 10;
delete ctestObj;
return 0;
}
What you're actually trying to do is have an instance of a struct inside your class. What you did was define a class within your class (which did not actually give your class a member of that type, but only scoped its definition).
So what you need to do is pull our the struct, from the class:
struct CTESTSTRUCT
{
// ...
};
And then give CTest a member of type CTESTSTRUCT
class CTest {
int value;
public:
CTest(int);
int getValue();
CTESTSTRUCT test;
~CTest();
};
Now you can access it like so:
int main() {
CTest * ctestObj;
ctestObj = new CTest(25);
int returnVal = ctestObj->getValue();
std::cout << "Value Returned: " << returnVal << std::endl;
std::cout << "structVal: " << std::endl;
ctestObj->test.testVal = 10;
delete ctestObj;
return 0;
}
I have broken down my issue into a small simple program.
I have a class myclass I have created in a separate .cpp file "classes.cpp" and declared in the header file "classes.h". myclass contains a variable a of which is initialized when instantiated. This makes variable a = 5.
My overall goal is to create a class in a separate .cpp file declared in a .h file which I can create multiple instances of in my main() program. The problem I am having is this.
In my main() function I create an instance of myclass called first.
my main program shows the variable a is set to the number 5.
If I want to change that number using a static function (and it has to be a static function as this relates to something much bigger in another program I am writing). I call the static function directly and in that static_function I create an instance of myclass and call the non_static_function because static functions have no implicit 'this' connecting them to an object.
In my non_static_function I change the value to the number 8. The problem is that the value of variable 'a' in 'first' remains at 5 when I want it to be 8. I need to change the value using first->static_function(8) and not by first->a = 8. . How can I do this?
Code below:
**main.cpp**
#include <iostream>
#include "classes.h"
using namespace std;
int main()
{
myclass *first = new myclass();
cout << "Myclass variable a is = " << first->a << endl;
first->static_function(8); // trying to change myclass variable 'a' to 8.
cout << "But" << endl;
cout << "the actual value of a is still: " << first->a << endl;
}
**classes.h**
#ifndef CLASSES_H_INCLUDED
#define CLASSES_H_INCLUDED
class myclass
{
public:
int a;
myclass();
void non_static_function(int x);
static void static_function(int x);
};
#endif // CLASSES_H_INCLUDED
**classes.cpp**
#include <iostream>
#include <cstdlib>
#include "classes.h"
using namespace std;
myclass::myclass()
{
a = 5;
}
void myclass::non_static_function(int x)
{
a = x;
cout << "The value for variable 'a' was 5 but is now: " << a << endl;
}
void myclass::static_function(int x)
{
myclass *p = new myclass();
p->non_static_function(x);
}
If you want every instance of myclass to have its own a and you want to call a static function to change it then you need to pass the instance you want changed to the static function. A static function can only modify static members of a class or the members of an instance that is inside its scope. Non static member functions can change any variable that is a member of the class.
class Foo
{
private:
int bar;
public:
static void static_function(int value, Foo & foo) { foo.bar = value; }
void non_static_function(int value) { bar = value; }
};
int main()
{
Foo foo;
Foo::static_function(8, foo);
// now bar will have the value of 8
foo.non_static_function(20);
// now bar will have the value of 20
}
I have finally found a way to deal with this small problem. Above the 'myclass' definition in classes.cpp I declare a 'myclass' variable
myclass *tgt; . Then in my constructor for 'myclass' I just allocate the instantiated object to a my global myclass variable of which I can access from the myclass definition tgt = this; Now I can use tgt in my static function to call the non_static_function in my 'myclass' definition and it all works perfectly.
NathanOliver, you are correct in saying that I need a class instance but the way I have done it here suits my needs. Passing the instance of myclass is certainly another way of doing this but it would require a global function above my 'myclass' definition.
Thanks for the help.
**main.cpp**
#include <iostream>
#include "classes.h"
using namespace std;
int main()
{
myclass *first = new myclass();
cout << "Myclass variable a is = " << first->a << endl;
first->non_static_function(8); // trying to change myclass variable 'a' to 8.
cout << "But" << endl;
cout << "The actual value of a is still: " << first->a << endl;
myclass *second = new myclass();
cout << "For the 'second' class the variable a is: " << second->a << endl;
second->non_static_function(23);
cout << "After calling the static function from 'second' the value of a is: " << second->a << endl;
cout << "And first->a is still: " << first->a << endl;
}
**classes.h**
#ifndef CLASSES_H_INCLUDED
#define CLASSES_H_INCLUDED
class myclass
{
public:
int a;
myclass();
void non_static_function(int x);
static void static_function(int x);
};
#endif // CLASSES_H_INCLUDED
**classes.cpp**
#include <iostream>
#include <cstdlib>
#include "classes.h"
using namespace std;
myclass *tgt; // *Add a global myclass variable above the myclass
definition*
myclass::myclass()
{
tgt = this; // *In the constructor allocate the instantiated class
//from main() to "tgt" .*
a = 5;
}
void myclass::non_static_function(int x)
{
a = x;
// Now see that the value of a is changed.
cout << "The value for variable 'a' was 5 but is now: "<< this->a << endl;
}
void myclass::static_function(int x)
{
tgt->non_static_function(x);
}