I have been working on a code in C++. But, I got stuck at a point.
This is a small prototype of my code::
#include <iostream>
using namespace std;
class Test{
private:
const int var;
void funPrivate(int arr[][var], int temp){
cout << arr[0][0] << endl;
}
public:
Test(int n) : var(n){};
void funPublic(){
int a[var][var];
funPrivate(a, var);
cout << "Hello";
};
};
int main()
{
Test t1(5);
t1.funPublic();
return 0;
}
I create a class funPublic() method, where I create a 2D array (using the const int var, which I declare as a private member inside my class Test) and then pass it to a private methode funPrivate(int arr[][var], int temp), where I print arr[0][0] (which shall be a garbage value).
But, when I try to run this program, I get an error::
error: invalid use of non-static data member 'Test::var'
My method funPrivate(int arr[][var], int temp) is a normal function (not a static function) and I don't a reason that I shall declare int var as static. Why does this happen.
Further, if I slightly modify the declaration of my method 'funPrivate(int arr[][var], int temp)' to this void funPrivate(int arr[][var]) then I get one more error:
error: 'arr' was not declared in this scope
Now, I don't know why does that happen. We pass the size of the array for our convenience, because there is no way to determine the size of the array in a function, but that shall not cause the error that arr was not declared in this scope.
I have been thinking and searching a lot, but still can't find an answer. Please help. Thanks for any help in advance. :D
The member variable var cannot be used in the declaration of an array like you are attempting in the function funPrivate:
void funPrivate(int arr[][var], int temp)
Your best option is to use std::vector<std::vector<int>>.
void funPrivate(std::vector<std::vector<int>> const& arr, int temp) {
cout << arr[0][0] << endl;
}
In the calling function, you can use:
void funPublic(){
std::vector<std::vector<int>> arr(var, std::vector<int>(var));
funPrivate(arr, var);
cout << "Hello";
};
Related
So I have a bunch of objects (subclasses of a parent class) with various functions each having different names, I might not have the resources to run all of the functions for each object so I want to have them in a priority list to run over time.
The code bellow is I believe forbidden by c++.
I get "C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function"
class A;
class Token;
list<Token> tokenList;
class Token{
public:
A* a; //Could be A or a child of A
int* function;
};
class A {
public:
A() {
Token token = Token();
token.a = this;
token.function = &A::hello;
tokenList.push_back(token);
}
int hello(){
cout << "hello" << endl;
return 0;
}
};
The code bellow should work but doesn't look elegant and also doesn't support subclasses having multiple functions they could pass to the list, is there a better way to do this I am missing?
class A;
list<A*> aList;
class A {
public:
virtual int funct();
};
class B : public A{
public:
virtual int funct(){
hello();
return 0;
}
int hello(){
cout << "hello" << endl;
return 0;
}
};
int main(){
//remove objects from list and run their functions in a loop until list is empty or max number of functions were run
Thanks Ted
Solution: Using the first example as mentioned I changed int* function; to int (A::*function)();. Then I can run the function with something like this
A tmp = A();
Token token = *tokenList.begin();
A *a = token.a;
(a->*token.function)();
}
The problem is that in your code int* function; is a pointer to an integer and not a pointer to a function.
If you would define it as int (*function)(); you could easily do what you want. But it would still not work with member functions.
So you need to define it as a pointer to a member function: int (A::*function)();
Here an example to make it work:
class Token{
public:
A* a; //Could be A or a child of A
int (A::*function)(); // pointer to member function with no arg, returning int
};
class A {
public:
A() {
Token token = Token();
token.a = this;
token.function = &A::hello; // Use the address of member function
tokenList.push_back(token);
}
int hello(){
cout << "hello (" << this <<")"<< endl; // added the address of a to see for which object
return 0;
}
};
int main() {
A a;
A b;
for (auto& token : tokenList )
(token.a->*token.function)(); // invoke the member function on the object pointer
}
Online demo
I didn't notice that your tokenList was a global variable. This is rather risky, as everything you create an A (including a temporary one), the tokenList will be updated. When you'll execute it, you'll therefore risk of having dangling pointers, i.e. pointing to an A instance that has already destroyed.
This question already has answers here:
How to use a member variable as a default argument in C++?
(4 answers)
Closed 1 year ago.
I tried to set a default parameter to a member variable, it gave me this bug.
[cquery] invalid use of non-static data member 'num'
code
#include <iostream>
class Test{
private:
int val = 0;
public:
void print_num(int num = val){
std::cout << num << '\n';
}
}
int main(){
Test test;
test.print_num();
return 0;
}
Despite it being quite obvious what this would mean, you just can’t. The usual workaround is to provide an overload that (implicitly) uses this to get the member value.
In order to set a default value for a function parameter to a class member, the member must be static.
Citing the documentation,
Non-static class members are not allowed in default arguments
However, given the context of your code sample I doubt this is what you want to do (as every instance of Test class will point to the same val. Citing the docs:
Static members of a class are not associated with the objects of the class: they are independent variables
If you make val static in your example, and have multiple instances of Test in use by your code, you can (and very likely will) have some unexpected behavior. Consider:
#include <iostream>
class Test{
private:
static int val;
public:
void print_num(int num = val){
std::cout << num << '\n';
}
void set_val(int num) {
val = num;
}
}
int Test::val = 0;
int main(){
Test test1;
test1.set_val(1);
Test test2;
test2.set_val(2);
test1.print_num(); // results in "2"
return 0;
}
A better alternative would be to pass a pointer to your function like this:
#include <iostream>
class Test{
private:
int val = 0;
public:
void print_num(int* numptr = nullptr){
int num = (numptr ? *numptr : val);
std::cout << num << '\n';
}
}
int main(){
Test test;
test.print_num();
return 0;
}
Or, as described by Davis Herring, use an overload:
#include <iostream>
class Test{
private:
int val = 0;
public:
void print_num(int num){
std::cout << num << '\n';
}
void print_num() {
return print_num(val); // return is irrelevant here, but my preferred coding style
}
}
int main(){
Test test;
test.print_num();
return 0;
}
Edited to reflect the comment and example.
Your function definition doesn't actually know what val is because it doesn't actually live inside of your class. The compiler is actually making a function that contains your class as a parameter and abstracts away all of that. You'll want to set num to val within the function body.
The following is a class template that implements a stack using an array:
#include <iostream>
using namespace std;
template <typename T>
class stack {
public:
stack (int priv_size) {
T a[priv_size];
top = 0;
}
stack (const stack &s) {
T b[priv_size];
for (top=0; top<s.priv_size; top++) {
b[top] = s.a[top];
}
top++;
}
~stack () {}
const stack& operator = (const stack &s) {
T b[s.priv_size];
for (top=0; top<s.priv_size; top++) {
b[top] = s.a[top];
}
top++;
}
bool empty () {
return top == 0;
}
void push (const T &x) {
a[top++] = x;
}
T pop () {
T c = a[--top];
return c;
}
int size () {
return priv_size;
}
friend ostream& operator << (ostream &out, const stack &s) {
int i;
out << "[";
for (i=0; i<s.top-1; i++) {
out << s.a[i] << ", ";
}
if (i == s.top-1) out << s.a[s.top-1];
out << "]";
return out;
}
private:
int priv_size;
int top;
T a[];
};
int main () {
stack<int> s(10);
cout << "stack s is empty: " << s << endl;
s.push(42);
s.push(17);
cout << "stack s has 2 elements: " << s << endl;
cout << "Removing " << s.pop() << " from the stack..." << endl;
return 0;
}
However as i was trying out the different methods of the class in main I realized that although priv_size is initialized to the value of 10 here: stack<int> s(10); it loses its value right after the constuctor is called.
When i tried debugging in my IDE i realized that once the constructor stack (int priv_size) is called it created another variable priv_size that is initialized to the value of 10 instead of using the priv_size member of the class. The previous can also be seen here:
class member priv_size memory address (image)
and here:
unwanted variable priv_size memory address (image)
where the two variables are stored in different memory slots.
Why are the two variables different and why is the one in the second image created in the first place?
I have also tried implementing the class methods outside of the class, like this:
stack<T>::stack (int priv_size) {
T a[priv_size];
top = 0;
}
but i get these two error messages:
Member declaration not found
Type 'T' could not be resolved
What is going on here?
Thanks in advance.
PS: I am aware there are a couple very similar questions posted already, but the answers to those do not seem to fit my problem as my issue seems to be in the class itself and not in main or any other function.
Here are two links to some similar questions:
C++ Class members lose values assigned in a member function
Losing a data member of a base class after the constructor is called
stack (int priv_size) {
T a[priv_size];
top = 0;
}
Problem 1: Your constructor doesn't initialise the member a. It creates a local array.
Problem 2: The size of the array is not a compile time constant. The program is ill-formed.
Problem 3: You don't initialise the priv_size member either.
private:
int priv_size;
int top;
T a[];
Problem 4: You didn't specify size of the array member a. The program is ill-formed.
although priv_size is initialized to the value of 10 here: stack s(10); it loses its value right after the constuctor is called.
Your assumption is wrong. The constructor doesn't set the value of priv_size member, so no value was lost.
where the two variables are stored in different memory slots.
As far as I can tell, one variable is the parameter of the constructor and the other is the member variable that you didn't initialise.
Type 'T' could not be resolved
What is going on here?
To define a template, you need to use the keyword template and specify the template parameters. Like this for example:
template <typename T>
stack<T>::stack (int priv_size) {
Why are the two variables different and why is the one in the second image created in the first place?
Because you declared two different variables.
Its the same issue as in :
struct foo {
int x;
foo(int a) {
int x = a;
}
};
foos constructor declares a local variable named x which shadows the member x and the member x is not initialized. Same with an array:
struct bar {
int a[5];
bar() {
int a[5];
}
};
The member a and the a in the constructor are two distinct arrays.
This is only answering your question, but there are more problems in your code. When you need an array whose size is only known at runtime you should use std::vector.
There are multiple issues with your code. For instance, T a[priv_size]; requires that priv_size is a compile-time constant. And in stack (const stack &s) {T b[priv_size];, the local variable b goes out of scope when the copy ctor ends, while the member a remains uninitialized.
How much memory would it take to declare a function pointer. How about a function pointer pointing to a member function of a class?
[EDIT:] I guess my question wasn't clear. I am aware a function pointer to a member function takes up more memory space, I am wondering why...
The answer is platform-dependent. You could find the answer for your specific platform by using sizeof.
Size of pointer to member function may not necessarily be the same as that of a regular function pointer, so you should write a test to output them both:
#include <iostream>
using namespace std;
void foo() {}
struct C {
void bar();
};
int main() {
cout << sizeof(&foo) << endl;
cout << sizeof(&C::bar) << endl;
return 0;
}
Demo.
It's up to the implementation, but typically a pointer to a member function takes up the same amount of space a regular pointer takes up, plus the amount of space the offset to the this pointer takes, which is typically the same size as a pointer. So you would expect a pointer to a member function to be twice the size of a regular pointer.
Consider:
#include <iostream>
using namespace std;
class Base
{
public:
int q;
Base() { ; }
void BaseFunc () { cout << this << endl; }
};
class Derived : public Base
{
public:
int r;
Derived() { ; }
virtual void DerivedFunc () { cout << this << endl; }
};
int main ()
{
Derived f;
f.BaseFunc();
f.DerivedFunc();
void (*p1)();
void (Derived::*p2)();
cout << sizeof(p1) << " " << sizeof(p2) << endl;
}
Example output:
0x7fffe4c3e328
0x7fffe4c3e320
8 16
So a pointer to a member function has to store two pieces of information -- which function to call and how to adjust the this pointer to point to the right section of the member data.
And for those who think the adjuster can be computed from the types, try this main:
int main ()
{
Derived f;
void (Derived::*p1)();
p1 = &Derived::BaseFunc;
(f.*p1)();
p1 = &Derived::DerivedFunc;
(f.*p1)();
}
The two invocations of (f.*p1)(); require different adjusters even though the types are the same. And, of course, invoking BaseFunc through a Base::(*)() pointer would require a different adjuster from invoking the same function through a Derived::(*)() pointer.
This is weird (MSVC2012):
using namespace std;
class MyClass
{
public:
int membervar;
};
template< int (MyClass::*var) > struct A
{
void print()
{
cout << var;
}
};
int main(int argc, char *argv[])
{
struct A <&MyClass::membervar> object;
object.print();
}
This code compiles and actually couts "1". Where does it get it?? What object does the membervar belong to? I thought I needed an object to access a data member
This code compiles and actually couts "1". Where does it get it?
What happens is that in:
int (MyClass::*var) = &MyClass::membervar;
cout << var;
Because there is no shift operator that takes a stream and a member pointer, another shift operator gets chosen:
std::ostream::operator<<(bool);
In other words, it prints var after converting it to bool.
This code compiles and actually couts "1". Where does it get it??
What you are trying to print is a pointer to a member function.
It's getting converted to a bool. And that bool is evaluating as true, meaning it's non-zero.