Access an undeclared struct? - c++

I there a way to access a struct that has not been declared yet?
//Need to some how declare 'monitor' up here, with out moving 'monitor' above 'device'
//because both structs need to be able to access each others members
struct{
int ID = 10;
int Get__Monitor__ID(){
return monitor.ID; //obvioulsly 'monitor' is not declared yet, therefore throws error and is not accessible
}
} device;
struct{
int ID = 6;
int Get__Device__ID(){
return device.ID; //because 'device' is declared above this struct, the ID member is accessible
}
} monitor;

In this particular case, you can define the function prototype in the struct, and the definition can come later.
struct device_t {
int ID = 10;
int Get__Monitor__ID();
} device;
struct monitor_t {
int ID = 6;
int Get__Device__ID();
} monitor;
int device_t::Get__Monitor__ID() {
return monitor.ID;
}
int monitor_t::Get__Device__ID() {
return device.ID;
}

Related

Is this a valid workaround to avoid "invalid use of member ‘X::XX’ in static member function"?

I was working on someone else's project, and I ran into an issue where the author's static function was preventing me from doing what I wanted. I wanted the function to modify a member variable I had created, which can't happen if the object was never instantiated.
As expected, accessing Foo::number from the static function Foo::foobar() causes this error:
staticvspointer.cpp:20:5: error: invalid use of member ‘Foo::number’ in static member function
My two options are to make the variable "number" a global, or make the function not static.
int NUMBER; //this could be global, but would make the large project messy
//class has a static function
class Foo {
public:
Foo();
static int foobar();
int number;
};
//make member function not static
class Bar {
public:
Bar();
void foobar(int);
int number;
};
Foo::Foo() {
}
int Foo::foobar() {
//can't access "number = 2;" in static function.
NUMBER = 2; //CAN access global though
return 2;
}
Bar::Bar() {
}
void Bar::foobar(int number) {
this->number = number;
}
int main() {
//1.) using a static function to get 2
int a = Foo::foobar();
int b = a + 2;
//b = 4
//2.) using a pointer to get ClassName::memberVariable, and then deleting it.
Bar* bar = new Bar;
bar->foobar(2);
b = bar->number + 2;
delete bar;
//b still = 4
//3.) using a global
Foo::foobar();
b = NUMBER + 2;
//b = 4 again
return 0;
}
I assume the problems this may or may not cause are dependent on the project, but I can't think of a reason not to do this.
Is there anything wrong with method #2? Is it a proper use of pointers? Is it readable or confusing? For some reason it feels wrong to me.

Getting a value from a nested class in c++

Please I am trying to print out the value of a nested class from the private access specifier.
#include <iostream>
#include <cstdlib>
using namespace std;
class cal{
private:
int a = 0;
public:
int setNum(int m){
a = m;
}
void getNum(){
cout<<"the number is: "<<a<<endl;
}
class area{
public:
int setMan(int z){
cal obj;
obj.setNum(z);
return 1;
}
};
};
int main(){
cal::area obj2;
obj2.setMan(200);
cal obj3;
obj3.getNum();
'
return 0;
}
cal::area obj2;
obj2.setMan(200); is to set 200 to the nested class area and into the function setMan, of which setMan which pass the same value to the int setNum(int m){a = m;} this will set the value of a to "200". Then I wanted to print out the value of a but it displays 0 instead of 200.
Defining a nested class only provides a definition for a nested class. If you want to have a member of that class you have to declare it:
struct cal {
struct area {}; // class definition
area m_area; // member
};
int setMan(int z){
cal obj;
obj.setNum(z);
return 1;
}
The object obj is a temporary auto object and would be destroyed when you return from the function. By the way, "set" functions should not return values, returning 1 is confusing.
If you wish to connect objects somehow consider the composition or aggregation. For example:
// ...
class area{
public:
area(cal& obj) : obj(obj);
int setMan(int z){
obj.setNum(z);
return 1;
}
cal &obj;
};
// ...
int main(){
cal obj;
cal::area obj2(obj);
obj2.setMan(200);
obj.getNum();
return 0;
}
Anyway, that is just an artificial example, I don't see the reason you make area a nested class, the reason of setting values to cal from area, etc.

Accessing multilayered structs results in error

I'm working on a homework assignment that involves creating structures for vending machines around campus. I'm getting the error "'vendingMachines' was not declared in this scope" and I can't figure out the solution. Would I have to run a for loop in main to declare the vendingmachines struct?
struct Location
{
std::string buildingName;
int floorLevel;
};
struct Drink
{
std::string drinkName;
float drinkSize;
float drinkPrice;
};
struct VendingMachine
{
Location machineLocation;
Drink drinkTypes[10];
};
struct AllVendingMachines
{
VendingMachine vendingMachines[5];
};
int checkPurchase(std::string buildingName, int floorLevel, std::string drinkName, f$
{
bool correct = true;
for (int i = 0; i < 5; i++)
{
if (vendingMachines[i].machineLocation.buildingName != buildingName)
{
correct = false;
}
if (vendingMachines[i].machineLocation.floorLevel != floorLevel)
{
correct = false;
}
for (int c = 0; c < 10; c++)
{
if (vendingMachines[i].drinkTypes[c].drinkName != drinkName)
{
correct = false;
}
if (vendingMachines[i].drinkTypes[c].drinkSize != drinkSize)
{
correct = false;
}
}
}
if (correct == true)
{
return 1;
}
else
{
return 0;
}
}
You're attempting to access vendingMachines in checkPurchase().
However, that's a member of the struct AllVendingMachines. Which means each AllVendingMachines object will have a vendingMachines array. So whose vendingMachines are you trying to access?
The simplest solution I can see would be to take an AllVendingMachines object as a function argument:
int checkPurchase(std::string buildingName, int floorLevel, std::string drinkName, AllVendingMachines machines)
{
bool correct = true;
for (int i = 0; i < 5; i++)
{
if (machines.vendingMachines[i].machineLocation.buildingName != buildingName)
{
correct = false;
}
// ...
You have declared vendingMachines to be part of struct AllVendingMachines, but you have never created an instance of that struct. Therefore, not a single instance of the member array 'vendingMachines' exists.
You could simply make the array vendingMachines a global variable, i.e. move it out of struct AllVendingMachines, or you could create a global instance of struct AllVendingMachines, by changing the declaration to the following:
struct AllVendingMachines
{
VendingMachine vendingMachines[5];
} all_vending_machines_global_instance;
In the latter case, you must change all references to vendingMachines[i] in the function checkPurchase to all_vending_machines_global_instance.vendingMachines[i].
I don't want to encourage the use of long variable names, I just gave it this long name for clarity.
Alternatively, if you don't want to use global variables, you can make the function checkPurchase receive an additional paramater consisting of a pointer or reference to an instance of struct AllVendingMachines or directly to an instance of the vendingMachines member array.

Class method points to other method of other class

i was wondering if is possible make that a method of class points to another method of other class:
consider this:
// Class Foo:
class Foo
{
static int GetA(int a);
static int GetB(int b);
};
int Foo::GetA(int a)
{
return a * 2;
}
int Foo::GetB(int b)
{
return a * 4;
}
// Hooking class methods:
class HookFoo
{
static int HookGetA(int);
static int HookGetB(int);
};
int(HookFoo::*HookGetA)(int) = (int(HookFoo::*)(int))0x0; // (0x0 Memory address) or for example: &Foo::GetA;
int(HookFoo::*HookGetB)(int) = (int(HookFoo::*)(int))0x0; // (0x0 Memory address) or for example: &Foo::GetA;
I know it's possible do some like:
int(*NewHook)(int) = &Foo::GetA;
but how i can do for declare the methods into of a class?
Here is more or less what you tried to achieve (minimal, working example):
class Foo
{
public:
static int GetA(int a);
static int GetB(int b);
};
int Foo::GetA(int a)
{
return a * 2;
}
int Foo::GetB(int b)
{
return b * 4;
}
class HookFoo
{
public:
using FuncType = int(*)(int);
static FuncType HookGetA;
static FuncType HookGetB;
};
// Initialized with Foo::GetA
HookFoo::FuncType HookFoo::HookGetA = &Foo::GetA;
// nullptr'ed
HookFoo::FuncType HookFoo::HookGetB = nullptr;
int main() {
HookFoo::HookGetA(0);
}
For the methods in Foo are static, you can use a simple function pointer type to refer to them. You don't have to use (and can't use actually) a member function pointer in this case.
The using declaration helps to have a more readable code.
When you have correctly initialized your hooks, you can invoke them (thus the pointed functions) as you can see in the main.
I added a couple of visibility specifiers for your methods and data members were all private.
You can use function pointers.
Ex:
class A {
public:
static void say_hello() { cout << "Hello\n"; }
};
class B {
public:
static void(*hook)();
};
void(*B::hook)() = A::say_hello;
int main()
{
B::hook();
}
If you need to hook into functions at a specific address, use a function pointer. You can't reassign functions like that
// typedef your function pointers, it makes the syntax a lot easier
typedef int(*FHook)(int);
class HookFoo
{
static FHook HookGetA;
static FHook HookGetB;
};
// assign to address
FHook HookFoo::HookGetA = (FHook)0x1234;
FHook HookFoo::HookGetB = (FHook)0x5678;
Of course its your job to make sure the addresses are correct.
the explicit function pointer types would be as such:
class HookFoo
{
static int (*HookGetA)(int);
static int (*HookGetB)(int);
};
int (*HookFoo::HookGetA)(int) = (int(*)(int))0x1234;
int (*HookFoo::HookGetB)(int) = (int(*)(int))0x5678;

How to access static class variable in static member function of same class?

I provide my sample:
class a
{
public:
static int m_n;
static int memfuc();
};
int a::memfuc()
{
int k =m_n;
return k;
}
But the following sample throws linker error: unresolved external symbols
You haven't defined (as opposed to declared) your static class member variable.
You could put this code in an implementation file (.cpp) somewhere:
int a::m_n = 123456;
You need to provide the implementation somewhere:
int a::m_n;
For a static, you have to define it as :
class a
{
public:
static int m_n;
static int memfuc();
};
int a::m_n = 0;
int main()
{
a my_a;
}
my2c
You need to define the member m_n, but you also need to access the member correctly.
You need to add:
int a::m_n = 0 // Or some number of your choice
Now m_n is defined you can access it anywhere, not just in other member functions:
int get_m_n()
{
int k = a::m_n;
return k;
}