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;
}
Related
I made an empty class having specific offset and want to derived class using that area..
like below code.. I use alignas()
#include <iostream>
#include <string>
#include <string.h>
using namespace std;
#pragma pack (push, 1)
class alignas(32) base
{
public:
base() { init(); }
void init() { memset(this, 0, 32); }
}; // sizeof(base) = 32
class derived01 : public base
{
int a;
int b;
}; // sizeof(derived01) = 32
class derived02 : public base
{
char a[20];
}; // sizeof(derived02) = 32
class item
{
int a;
base b;
int c;
public:
template <typename T>
inline T GetDerived()
{
return reinterpret_cast<T>(&b);
}
};
#pragma pack (pop)
int main()
{
cout << "ItemUnit :" << sizeof(base) << endl;
cout << "derived01 :" << sizeof(derived01) << endl;
cout << "derived02 :" << sizeof(derived02) << endl;
cout << "item :" << sizeof(item) << endl;
// I want to get Derived Class like this..
//item* i = new item();
//derived02 d = i.GetDerived<derived02>();
return 0;
}
and, it seemed to work as expected.. In LINUX.. (g++ 7.4)
# ./a
ItemUnit :32
derived01 :32
derived02 :32
item :40
but in MSVS2019, it returned..
ItemUnit :32
derived01 :32
derived02 :32
item :96
I also thought about other ways, but they have some....
UNION but, it cant using inheritance.. and I think it inconvenient to use.
make base class having char[32].. and derived having only functions to get,set using offset..
Is there any other good way?
please advice..
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.
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);
}
I've just made a template to detect if a data member of a class is static defined or not. The accessibility of the member isn't what it should be concerned about(Assuming the member is always accessible by the template) in this post. Here is the code with any symbols for testing:
#include <conio.h>
//#include <stdio.h>
#include <iostream>
struct A1
{
int a;
};
struct A2
{
static int a;
};
int A2::a{};
template < class My_Type >
struct TestStatic
{
template < typename raw_ty > static char fTest(...);
template < typename class_ty, typename arg_ty = decltype(class_ty::a) >
static int fTest(int, arg_ty & = class_ty::a);
enum nRes { result = sizeof(fTest<My_Type>(0)) - 1 };
};
int main(void)
{
int i;
i = TestStatic<A1>::result;
std::cout << i << std::endl;
i = TestStatic<A2>::result;
std::cout << i << std::endl;
_getch();
return(0);
}
The question is when it was built with g++ 4.8 the compiling passed but got the result as two '3's rather than one '0' and another '3'. Is there anything wrong?
Your approach is fundamentally flawed, because decltype(T::x) is perfectly valid for non-static members:
#include <iostream>
struct T
{
int x;
};
int main()
{
std::cout << sizeof(decltype(T::x)) << '\n';
}
// Output: 4
You can get what you want with std::is_member_pointer:
If T is pointer to non-static member object or a pointer to non-static member function, provides the member constant value equal true. For any other type, value is false.
#include <iostream>
#include <type_traits>
struct T
{
int x;
};
struct S
{
static int x;
};
int main()
{
std::cout << !std::is_member_pointer<decltype(&T::x)>::value << ' ';
std::cout << !std::is_member_pointer<decltype(&S::x)>::value << '\n';
}
// Output: 0 1
This works because access to members through the :: syntax results in a pointer-to-member only if the member is not-static; it is of course a normal variable access when the member is static.
Please have a look at the following code
GameObject.h
#pragma once
class GameObject
{
public:
GameObject(int);
~GameObject(void);
int id;
private:
GameObject(void);
};
GameObject.cpp
#include "GameObject.h"
#include <iostream>
using namespace std;
static int counter = 0;
GameObject::GameObject(void)
{
}
GameObject::GameObject(int i)
{
counter++;
id = i;
}
GameObject::~GameObject(void)
{
}
Main.cpp
#include <iostream>
#include "GameObject.h"
using namespace std;
int main()
{
//GameObject obj1;
//cout << obj1.id << endl;
GameObject obj2(45);
cout << obj2.id << endl;;
// cout << obj2.counter << endl;
GameObject obj3(45);
GameObject obj4(45);
GameObject obj5(45);
//Cannot get Static value here
//cout << "Number of Objects: " << GameObject
//
system("pause");
return 0;
}
Here, I am trying to record how many instances have been created. I know it can be done by a static data member, but I can't access it withing the Main method! Please help!
PS:
I am seeeking for a direct access, without a getter method
Your static variable, counter cannot be accessed because it isn't a member of GameObject. If you want to access the counter, you'll need to do something like this:
GameObject.h
#pragma once
class GameObject
{
public:
...
static int GetCounter();
...
};
GameObject.cpp
int GameObject::GetCounter()
{
return counter;
}
Then you can access the variable like:
cout << "Number of Objects: " << GameObject::GetCounter();
Of course, there are other ways of accessing a static variable, such as making the counter variable a static member of your GameObject class (which I would recommend).
In your code, counter is not a static member of your class, but just a good old global variable. You can read up on how to declare static member variables anywhere on the net, but here are some snippets:
GameObject.h
#pragma once
class GameObject
{
public:
GameObject(void);
GameObject(int);
~GameObject(void);
private:
int id;
// static members
public:
static int counter; // <<<<<<<<<<< declaration
};
ameObject.cpp
#include "GameObject.h"
int GameObject::counter = 0; // <<<<<<<<<<< instantiation
GameObject::GameObject(void)
{
counter++;
}
GameObject::GameObject(int i)
{
counter++;
id = i;
}
GameObject::~GameObject(void)
{
}
Main.cpp
#include <iostream>
#include "GameObject.h"
using namespace std;
int main()
{
GameObject obj2(45);
cout << "version one: " << obj2.counter << endl;
// second version:
cout << "version two: " << GameObject::counter << endl;
system("pause");
return 0;
}
Afaik accessing static members on an instance of that class should work fine, but it gives the wrong impression, you should prefer version two.
Never mind, I did it with a getter method. Closing thread