I'm trying to make this code work:
#include <iostream>
using namespace std;
int f(int x) {
return x+1;
}
class A {
public:
int g(int y);
};
int A::g(int y) = f;
int main() {
A test;
cout << test.g(3) << endl;
return 0;
}
It does not compile because of the line int A::g(int y) = f;.
What is the correct way to achieve that an external function can be used as a method?
You can use a pointer to function as a member of class A. Now assign function f to g member of A.
int f(int x) {
return x+1;
}
class A {
public:
int (*g)(int);
};
int main(){
A test;
test.g = f;
cout << test.g(10); // prints 11
}
You can accomplish the same by making your function a callable objects by implementing () operator. so you can have that as member of the class, and then it can normally be used as function on the class objects.
#include <iostream>
struct do_something{
int operator()(int num){
return num;
}
};
class test{
int sum;
public:
do_something fun;
};
int main(){
test obj;
std::cout << obj.fun(10);
}
Related
The usual method one'd use for normal variables (declaring outside the member functions & initializing inside a member function) doesn't work, as reference variables need to be initialized & declared in same line.
#include <iostream>
using namespace std;
class abc {
public:
int& var;
void fun1 (int& temp) {var=temp;}
void fun2 () {cout << abc::var << endl;}
abc() {}
};
int main() {
abc f;
int y=9;
f.fun1(y);
f.fun2();
return 0;
}
How to initialize a reference member variable inside a member function & access it inside other member functions - C++
Use a pointer.
#include <iostream>
using namespace std;
class abc {
public:
int* var;
void fun1 (int& temp) { var = &temp; }
void fun2 () { cout << *abc::var << endl; }
abc() {}
};
int main() {
abc f;
int y=9;
f.fun1(y);
f.fun2();
return 0;
}
I think this is the best you can do.
#include <iostream>
using namespace std;
class abc {
public:
int& var;
abc(int& temp) :
var(temp)
{}
void fun2 () {cout << abc::var << endl;}
};
int main() {
int y=9;
abc f(y);
f.fun2();
return 0;
}
A reference is a constant thing — it refers to the same integer for the entire lifespan of the object. That means you need to set it on construction.
int var; int& varref = abc::var;
This should work!
i have this sample:
#include <iostream>
using namespace std;
class A {
public:
int x;
A(int one) { x = one; }
int getX() { return x; }
};
void main()
{
A first(5);
first = 10;
}
which in here the constructor is called in both lines of main.
but if we had more than one variable in the class, is it possible to call the constructor with the operator =?
like in here:
class A {
public:
int x,y;
A(int one,int sec) { x = one; y=sec;}
int getX() { return x; }
int getY() { return y; }
};
and create a class variable using = like this?
A example=(50,40)
Yes, since C++11 you can do it with copy-list-initialization like this:
A example = {50, 40};
example = {40, 50};
I'm trying to pass a reference to a function in a class but am having trouble figuring out how to do it. So say I have a class test defined as such
#include <iostream>
class test {
public:
test () {};
~test () {};
void setA (int);
int getA (void);
private:
int a;
};
void test::setA (int A) { a = A; }
int test::getA (void) { return a; }
using namespace std;
int main ()
{
test T;
T.setA(5);
cout << "a = " << T.getA() << endl;
return 0;
}
That works fine but if I want to pass the values by reference
#include <iostream>
class test {
public:
test () {};
~test () {};
void setA (int);
int & getA (void);
private:
int a;
};
void test::setA (int & A) { a = A; }
int & test::getA (void) { return a; }
using namespace std;
int main ()
{
test T;
T.setA(5);
cout << "a = " << T.getA() << endl;
return 0;
}
I cannot figure out how to configure setA to pass by reference.
There are two issues with the code. First, the definition of setA does not match the declaration. You must make the declaration take in a reference as a parameter.
Change this:
void setA (int);
To this:
void setA (int&);
The second issue is that you are trying to pass an r-value (5) as a reference. You must pass in an l-value. You can do that by creating an int first and then passing that by reference:
int i = 5;
T.setA(i);
Full example:
#include <iostream>
class test {
public:
test () {};
~test () {};
void setA (int&);
int & getA (void);
private:
int a;
};
void test::setA (int & A) { a = A; }
int & test::getA (void) { return a; }
using namespace std;
int main ()
{
test T;
int i = 5;
T.setA(i);
cout << "a = " << T.getA() << endl;
return 0;
}
When you pass something by reference to a function in C++, the function does not keep the parameter in memory automatically. Thus, you have to declare it before so that it stays in memory throughout the entire function.
The 5 you tried to pass as a reference would go out of scope and get destroyed as soon as the function starts. The declared i variable is instead destroyed at the end of the main function.
The reason is because in order to pass by reference, you must have an lvalue, which is a fancy way of saying something that persists beyond a single use.
If you created an int variable, you would be able to pass it in by reference. In the code above, you attempted to pass in a raw integer value (5), which fails, since the compiler is expecting a reference to an int, not a raw integer value.
The following code would work:
int main ()
{
test T;
int myVariable = 4; // Need an actual variable to pass by reference.
T.setA(myVariable);
cout << "a = " << T.getA() << endl;
return 0;
}
However, if you want your function to take raw integer values like you showed in your second example, you must have a function definition like your first example, where all the function takes is an integer. Hope this helps!
Maybe you could try this:
#include <iostream>
class test {
public:
test() {};
~test() {};
void setA(int&&); // requires at least C++11
void setA(int&);
int & getA(void);
private:
int a;
};
void test::setA(int && A) { a = A; }
void test::setA(int&A) { a = A; }
int & test::getA(void) { return a; }
using namespace std;
int main()
{
test T;
int i = 5;
T.setA(i);
cout << "a = " << T.getA() << endl;
T.setA(8);
cout << "a = " << T.getA() << endl;
return 0;
}
In the example, int& passes a l-value while int&& passes a r-value as a reference.
I'm trying to design a piece of code that entails the use of an algorithm. The algorithm should be easily replaceable by someone else in the future. So in my LargeClass there has to be a way to invoke a specific algorithm.
I provided some example code below. My idea was to make an interface class IAlgorithm so that you have to provide an implementation yourself. I thought you could initialize it to which ever derived class you wanted in the constructor of the LargeClass. However the below code doesn't compile in VS2015 because IAlgorithm: cannot instantiate abstract class
My question: How should I design this in order to get the result I want?
Thanks in advance!
Algorithm.h
class IAlgorithm
{
protected:
virtual int Algorithm(int, int) = 0;
};
class algo1 : public IAlgorithm
{
public:
virtual int Algorithm(int, int);
};
class algo2 : public IAlgorithm
{
public:
virtual int Algorithm(int, int);
};
Algorithm.cpp
#include "Algorithm.h"
int algo1::Algorithm(const int a, const int b)
{
// Do something
}
int algo2::Algorithm(const int a, const int b)
{
// Do something
}
Source.cpp
#include "Algorithm.h"
class LargeClass
{
private:
IAlgorithm algo;
};
int main()
{
}
My first thoughts on this would be, why use such a primitive interface?
OK, we have a requirement that some process needs an algorithm sent into it. This algorithm must be polymorphic, it must take two ints and return an int.
All well and good. There is already a construct for this in the standard library. It's call a std::function. This is a wrapper around any function object with a compatible interface.
example:
#include <functional>
#include <iostream>
class LargeClass
{
public:
using algorithm_type = std::function<int(int,int)>;
LargeClass(algorithm_type algo)
: _algo(std::move(algo))
{}
int apply(int x, int y) {
return _algo(x,y);
}
private:
algorithm_type _algo;
};
int test(LargeClass&& lc) {
return lc.apply(5,5);
}
int divide(int x, int y) { return x / y; }
int main()
{
// use a lambda
std::cout << test(LargeClass{ [](auto x,auto y){ return x + y; } });
// use a function object
std::cout << test(LargeClass{ std::plus<>() } );
// use a free function
std::cout << test(LargeClass{ divide } );
// use a function object
struct foo_type {
int operator()(int x, int y) const {
return x * 2 + y;
}
} foo;
std::cout << test(LargeClass{ foo_type() } );
std::cout << test(LargeClass{ foo } );
}
I have one question about friend functions/classes. Consider the following code:
#include <iostream>
struct A
{
private:
int a = 5;
friend int foo(A a);
};
int foo(A a)
{
return a.a;
}
int a = foo(A());
int main(){ std::cout << a << std::endl; }
DEMO
It works fine and both int foo() within class scope and global scope refer to the same entity. Although, the declaration of int foo() within the class scope didn't introduce a name into the global scope. If it were then we would recieve a linker-error intstead of compile-error in the code:
#include <iostream>
struct A
{
private:
int a = 5;
friend int foo();
};
int a = foo(); //undeclared foo
int main(){ std::cout << a << std::endl; }
DEMO
I can't find explanation about this in the Standard. What it says is N3797:11.3/6 [class.friend]:
A function can be defined in a friend declaration of a class if and
only if the class is a non-local class (9.8), the function name is
unqualified, and the function has namespace scope.
So, it explains why the following code works fine:
#include <iostream>
struct A
{
private:
int a = 5;
friend int foo(A a)
{
return a.a;
}
};
int a = foo(A());
int main(){ std::cout << a << std::endl; }
DEMO
We defined the function in the friend declaration and, as the Standard said it became the member of the global namespace. But the rule covers the defintion, not declaration. Obviously, that's not any declaration is definition. So we can't apply one to the first example.
In the last program
#include <iostream>
struct A
{
private:
int a = 5;
friend int foo(A a)
{
return a.a;
}
};
int a = foo(A());
int main(){ std::cout << a << std::endl; }
The compiler finds definition of function foo only due to the argument dependent lookup.
You should consider the following section of the C++ Standard
3.4.2 Argument-dependent name lookup
2 For each argument type T in the function call, there is a set of
zero or more associated namespaces and a set of zero or more
associated classes to be considered. The sets of namespaces and
classes is determined entirely by the types of the function
arguments (and the namespace of any template template argument).
Typedef names and using-declarations used to specify the types do not
contribute to this set.
Thus in this program the compiler searches the function in the scope of the class because the argument of the function has the class type. If you will change the function definition for example the following way then the compiler will not find the function.
#include <iostream>
struct A
{
public:
A( int x ) : a( 2 * x ) {}
private:
int a;
friend int foo( int x )
{
A a( x );
return a.a;
}
};
int a = foo( 10 );
int main()
{
std::cout << a << std::endl;
return 0;
}
But if you add a declaration of the function in the scope where the class is defined then the compiler will see the function
#include <iostream>
struct A
{
public:
A( int x ) : a( 2 * x ) {}
private:
int a;
friend int foo( int x )
{
A a( x );
return a.a;
}
};
int foo( int );
int a = foo( 10 );
int main()
{
std::cout << a << std::endl;
return 0;
}
Here the program output is
20