I have the following code:
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
class A {
public:
int f();
int (A::*x)();
};
int A::f() {
return 1;
}
int main() {
A a;
a.x = &A::f;
printf("%d\n",(a.*(a.x))());
}
Where I can initialize the function pointer correctly. But I want to make the function pointer as static, I want to maintain single copy of this across all objects of this class.
When I declare it as static
class A {
public:
int f();
static int (A::*x)();
};
I am unsure of the way/syntax to initialize it to function f. Any resource would be helpful
A static pointer-to-member-function (I guess you already know this is different from a pointer to a static member function) is a kind of static member data, so you have to provide a definition outside the class like you would do with other static member data.
class A
{
public:
int f();
static int (A::*x)();
};
// readable version
using ptr_to_A_memfn = int (A::*)(void);
ptr_to_A_memfn A::x = &A::f;
// single-line version
int (A::* A::x)(void) = &A::f;
int main()
{
A a;
printf("%d\n",(a.*(A::x))());
}
Related
I'm writing a class which is wrapped in a namespace named cs. I am using a library whose one of the function takes a function pointer. The function have to modify some of the protected members of the class so I wrote a free function in the same cs namespace and made it a friend function of the class. Doing that made it available for the clients to use that function. But The function MUST be inaccessible from the client due to obvious reasons.
An example code is here:
#include "lib.h"
namespace cs{
class A
{
protected:
int x;
float y;
friend int myFunc(void* userdata, int valInt, float valFloat);
public:
void abc()
{
libFunc(this, myFunc);
}
};
void myFunc(void *userdata, int x, float y){
// I would like this function to be inaccessible from the client
A *obj = (A*) userdata;
obj->x = x;
obj->y = y;
}
}
If you want to make a free function inaccessible in another compilation unit, you may use a nested anonymous namespace:
namespace cs{
class A
{
protected:
//...
friend int myFunc(int valInt, float valFloat);
public:
void abc();
};
namespace { // anonymous nested namespace
int myFunc(int x, float y){
...
}
}
void A:: abc() {
libFunc(this, myFunc);
}
}
I have a private static const member in class, and in the class implementation I have static function that tries to use this const, but it gives me errors.
//A.hpp
class A {
static const int X = 1; //<<problem here
// ....
}
and I have
//A.cpp
static int DoSomething();
// ....
static int DoSomething {
int n = A::X; //<<problem here
//....
}
and I get within this context when I try to use X from DoSomething and ‘const int A::X’ is private in the static const int X = 1;.
How can I fix that?
You are trying to access a private member of A from a free function. This is not allowed.
You should make it public, eg:
class A {
public:
static const int X = 1;
}
An alternative solution to Jack's answer is to make the function DoSomething() non-static and declare it as a friend of class A:
//A.hpp
class A {
static const int X = 1;
// ....
friend int DoSomething();
};
//A.cpp
int DoSomething() {
int n = A::X;
//....
}
I have header.h
Class A
{
int var_1;
int var_2;
};
Class b
{
private: static A var[MAX];
.....
};
But how can I initialize this property in header.cpp?
Give A a default constructor that sets the ints to 0s or something.
A b::var[MAX] = {};
In implementation file:
A b::var[] = {}; // static member definition
// A() is called for each member so you might want
// to implement it
example:
#define MAX 10
class A
{
int var_1;
int var_2;
};
class b
{
private:
static A var[MAX]; // static member declaration
};
A b::var[] = {}; // static member definition
int main() {
return 0;
}
http://ideone.com/ndkPmX
Assuming there is class A with the public constructor that takes no arguments (or default constructor):
File b.h :
#include "a.h"
// global constant:
const int MAX = 10;
class B {
private:
static A var[MAX]; // declaration
};
File b.cpp :
#include "b.h"
A B::var[MAX] = {}; // definition
The call that generates the unresolved external symbol:
#include <string.h>
#include "GContext.h"
#include "GBitmap.h"
#include "GColor.h"
int main(int argc, char** argv) {
const int W = 100;
const int H = 100;
GContext* ctx = GContext::Create(W, H);
The abstract class method signature:
#ifndef GContext_DEFINED
#define GContext_DEFINED
#include "GTypes.h"
class GBitmap;
class GColor;
class GContext {
public:
GContext() {}
virtual ~GContext() {}
virtual void getBitmap(GBitmap*) const = 0;
virtual void clear(const GColor&) = 0;
static GContext* Create(const GBitmap&);
static GContext* Create(int width, int height);
};
#endif
And the Current Derived Class Implementation and Method Signature:
#include "GColor.h"
#include "GPixel.h"
#include "GBitmap.h"
#include "GContext.h"
#include "GTypes.h"
class myGContext : public GContext
{
public:
myGContext() : GContext(){}
static const GBitmap* bitmap;
void getBitmap(GBitmap* bitmap) const
{
}
void clear(const GColor& gcolor)
{
int length = sizeof( (GPixel)(bitmap->fPixels) ) / sizeof(GPixel);
for (int i = 0; i < length; i++)
{
(bitmap->fPixels)[i]
}
}
static GContext* Create(const GBitmap& gbitmap)
{
GContext::Create(gbitmap);
bitmap = &gbitmap;
GContext* g = new myGContext();
return g;
}
static GContext* Create(int width, int height)
{
GContext::Create(width,height);
GContext* g = new myGContext();
return g;
}
};
So I understand that I need to define both types of the function GContext::Create() to resolve the external symbol error, but I need to define them in my derived Class. Which I thought I was doing right, any ideas?
no Inheritance does not work, this is not like a virtual function.
I'm not exactly sure what you're trying to do but if you
Need to have static functions
Need both base and derived classes to have their own implementation
derived needs access to the base class' functions
this is all achievable:
#include <iostream>
class A {
public:
A() {}
static void f() { std::cout << "A f" << std::endl; }
};
class B : public A {
public:
B() {}
static void f() { std::cout << "B f" << std::endl; }
};
int main(int argc, char* argv[]) {
A a;
B b;
a.f();
b.f();
b.A::f();
return 0;
}
Output is
A f
B f
A f
I think it is just because you static method is not defined in your base class. From here it is said that LNK2019 can also occur when a static data member is declared but not defined.
Also, be careful when you try to redefine static methods inside subclasses:
You cannot override a static method in a subclass, you can only hide it.
And from the C++ standard:
9.4.1 Static member functions [class.static.mfct]
2/ A static member function shall not be virtual. There shall not be a static and a non-static member function with the same name and the same parameter types (13.1). A static member function shall not be declared const, volatile, or const volatile.
Example:
#include <iostream>
class Foo
{
public:
static void func() { std::cout << "Foo::func" << std::endl; }
};
class Bar : public Foo
{
public:
static void func() { std::cout << "Bar::func" << std::endl; }
};
int main(void)
{
Foo::func(); // Works
Bar::func(); // Works
Foo foo;
Bar bar;
foo.func(); // Works
bar.func(); // Works
bar.Foo::func(); // Works
Foo* foobar = new Bar;
foobar->func(); // Not the result expected
// Because no override.
return 0;
}
EDIT: declaring them private was a typo, I fixed it:
Relating to another question, if I declared a static variable in a class, then derived a class from that, is there any way to declare the static variable as individual per each class. Ie:
class A:
{
public:
static int x;
};
class B:A
{
public:
const static int x;
};
does that define TWO DIFFERENT static variables x, one for A and one for B, or will I get an error for redefining x, and if I do get an error, how do a I create two seperate static variables?
When you're using static variables, it might be a good idea to refer to them explicitly:
public class B:A
{
public const static int x;
public int foo()
{
return B::x;
}
}
That way, even if the class "above" yours in the hierarchy decides to create a similarly-named member, it won't break your code. Likewise, I usually try to us the this keyword when accessing normal member fields.
Updated to use C++ syntax.
That creates two separate static variables.
Note that you have implicitly declared these private:
class A:
{
private:
static int x;
};
class B:A
{
private:
const static int x;
};
Which means the variables are not in competition with each other.
As already said, that creates two separate variables :
A::x;
// and
B::x;
In fact if you try to use just 'x' in a method of B, only the closer scope definition will be used until you are more precise :
#include <iostream>
class A
{
protected:
static int x;
public:
A() { x = 7; }
};
int A::x = 22;
class B:A
{
static const int x = 42;
public:
int a_x() const { return A::x; }
int b_x() const { return B::x; }
int my_x() const { return x; } // here we get the more local variable, that is B::x.
};
int main()
{
B b;
std::cout << "A::x = " << b.a_x() << std::endl;
std::cout << "B::x = " << b.b_x() << std::endl;
std::cout << "b's x = " << b.my_x() << std::endl;
std::cin.ignore();
return 0;
}
Outputs:
A::x = 7
B::x = 42
b's x = 42
Someone mentioned that accessibility might limit accessibility : making the base variable private will not make it accessible to the child class.
However, if the variable have to be protected or public, use an explicit access method or rely on the local scope rule I just demonstrated.
If you want a static variable that is individual to each class that uses A - you can use a template class.
For e.g.
template<class T> struct A
{
A() { ++s_var; }
static int s_var;
};
template<class T> int A<T>::s_var;
stuct B :A<B> {
B() { ++s_var; } // this is a different s_var than the one used by 'C' below
};
struct C : A<C> {
C() { ++s_var; } // this is a different s_var than the one used by 'B'
};