I have tried to call the class function computeCivIndex() from another class I have defined but it says that there was an undefined reference to LocationData::computeCivIndex(string, int, int, float, float) and a defined an unused funciton computeCivIndex(string int, int, float, float) in my LocationData.cpp
And I used g++ -Wall -W LocationData.h LocationData.cpp PointTwoD.h PointTwoD.cpp MissionPlan.cpp -o myProg.o to compile.
LocationData.h
static float computeCivIndex( string sunType_, int noOfEarthLikePlanets_, int noOfEarthLikeMoons_, float aveParticulateDensity_, float avePlasmaDensity_ ); /*calculate the possibility of life in the star system*/
};
LocationData.cpp
static float computeCivIndex( string sunType_, int noOfEarthLikePlanets_, int noOfEarthLikeMoons_, float aveParticulateDensity_, float avePlasmaDensity_ )
{
int sunTypePercent = 0;
float civIndex;
// convert string suntype to suntype percent
if (sunType_ == "Type O")
{
sunTypePercent = 30;
}
if (sunType_ == "Type B")
{
sunTypePercent = 45;
}
if (sunType_ == "Type A")
{
sunTypePercent = 60;
}
if (sunType_ == "Type F")
{
sunTypePercent = 75;
}
if (sunType_ == "Type G")
{
sunTypePercent = 90;
}
if (sunType_ == "Type K")
{
sunTypePercent = 80;
}
if (sunType_ == "Type M")
{
sunTypePercent = 70;
}
//compute the CivIndex
civIndex = ( (sunTypePercent/100) - (aveParticulateDensity_ + avePlasmaDensity_)/200 ) *
(noOfEarthLikePlanets_ + noOfEarthLikeMoons_);
return civIndex;
}
MissionPlan.cpp
float computeCivIndex[arraySize];
//compute civ index for all stored records
for (int i = 0; i < (entryNo+1); i++)
{
string suntype = locData[i].getSunType();
int earthlikeplanets = locData[i].getNoOfEarthLikePlanets();
int earthlikemoons = locData[i].getNoOfEarthLikeMoons();
float partdensity = locData[i].getAveParticulateDensity();
float plasdensity = locData[i].getAvePlasmaDensity();
locData[i].computeCivIndex(suntype,earthlikeplanets, earthlikemoons , partdensity, plasdensity);
point2d[i].setCivIndex(computeCivIndex[i]);
}
cout << "Computation Completed! ( " << entryNo <<" records were updated )" << endl;
That is because you have not implemented the function!
You need to qualify the function appropriately in the implementation to tell the compiler that you are actually implementing the class functions:
SomeClass.h:
class SomeClass
{
void someFunction();
static void someStaticFunction();
};
SomeClass.cpp:
void SomeClass::someFunction() { }
void SomeClass::someStaticFunction() { } // static must not be repeated!
If you do simply
void someFunction() { }
static void someStaticFunction() { }
you define two additional functions at namespace scope, not at class scope as you intended. By declaring them static, you additionally limit accessibility to from within the .cpp file they are defined in, so won't be found when compiling other .cpp files.
Be aware that static within a class has a completely different meaning than at global scope (and another different meaning within a function body) - Coming to that later. First, another error, though:
locData[i].computeCivIndex(suntype,earthlikeplanets, earthlikemoons , partdensity, plasdensity);
Via operator. (or operator-> on pointers), you can only call non-static functions (this is different from Java), static functions need to be called with class scope:
LocationData::computeCivIndex(suntype,earthlikeplanets, earthlikemoons, partdensity, plasdensity);
Meaning of static at different scopes:
class SomeClass
{
static void f(); // static class function as you know
};
static void anotherF(); // free/global function - static limits accessibility!
void yetAnotherF()
{
static int n = 0; // see below
}
static void anotherF(); is the C way to limit acessibility - the C++ variant of is placing the function into an anonymous namespace:
namespace
{
void anotherF() { }
}
Finally: static within functions: This way, you declare some kind of global variable that is only accessible from within the function. It is initialised only the first time you call the function, and the previous value of will be available on all subsequent calls:
void f()
{
static int x = 0;
printf("%d ", ++x);
}
int main()
{
f();
f();
f();
return 0;
}
Output will be: 1 2 3.
More details you find here.
Related
After reading StackOverflow's discussions and implementing some advices, I have these pieces of code intended just to test the behavior of static members of a class.
Here is the header, which has the class declaration:
class OurClass
{
private:
static int x, y;
public:
static void setVals(int valx, int valy);
static int getValx();
static int getValy();
static void initialize();
};
And here is the cpp file, which has the definition of these members as well as the main() function:
#include <iostream>
#include "OurClass.hpp"
using namespace std;
void OurClass::initialize()
{
static int x = 0;
static int y = 0;
}
void OurClass::setVals(int valx, int valy)
{
static int x = valx;
static int y = valy;
}
int OurClass::getValx()
{
static int x;
return x;
}
int OurClass::getValy()
{
static int y;
return y;
}
int main(void)
{
OurClass::inicializa();
cout << "Provide x and y..." << endl;
OurClass::setVals(cin.get(), cin.get());
cout << "Value of x: " << OurClass::getValx() << endl;
cout << "Value of y: " << OurClass::getValy() << endl;
return 0;
}
So, assuming that a static variable exists for the class, and that static functions only access static variables, I was expecting that x and y would have the values that we read from the keyboard with the setVals() call in main(). But when printing their values in the couts, they still have the value we assigned in the initialize() function (which BTW was another suggestion I got here, that is, initialize a static variable in a method).
I am also unable to refer directly to the variables by OurClass::x or y even if I make them public.
Do you guys know why?
First you need to access your local class's static variable instead declaring new method local variables in each method. Check below.
class Out {
private:
static int x, y;
public:
void set(int x, int y);
int getSum();
};
int Out::x = 0;
int Out::y = 0;
void Out::set(int x, int y) {
Out::x = x;
Out::y = y;
}
int Out::getSum() {
return Out::x + Out::y;
}
Instead of setting values of existing variables this code creates new local static variables. Fix:
void OurClass::initialize()
{
x = 0;
y = 0;
}
void OurClass::setVals(int valx, int valy)
{
x = valx;
y = valy;
}
int OurClass::getValx()
{
return x;
}
int OurClass::getValy()
{
return y;
}
And add the definitions of those static variables in a .cc file (not header):
int OurClass::x;
int OurClass::y;
I created a class named result_line and have been having problems with it's constructor. That is that it wasn't being assigned the expected values.
I have since created a similar, but more frugal, class named rsltline and this appears to work.
Here's the 2 classes :-
result_line
class result_line {
private:
HWND rwnd;
int result_flags;
int result_extraflags;
public:
result_line(HWND, int, int);
~result_line();
HWND result_lineGetHWND();
void result_lineSetHWND(HWND);
int result_lineGetFlags();
int result_lineGetExtraFlags();
DINT result_lineGetBothFlags();
void result_lineSetFlags(int);
void result_lineSetExtraFlags(int);
void result_lineSetBothFlags(int,int);
void result_lineSetBothFlags(DINT);
};
// Constructor for result_line(HWND) and result_line(HWND, result_flag)
result_line::result_line(HWND rwnd, int result_flags, int result_extraflags) {
rwnd = rwnd;
result_flags = 30;
result_extraflags = 40;
}
result_line::~result_line() {}
HWND result_line::result_lineGetHWND() { return rwnd; }
int result_line::result_lineGetFlags() { return result_flags; }
int result_line::result_lineGetExtraFlags() { return result_extraflags; }
DINT result_line::result_lineGetBothFlags() { return DINT(result_flags,result_extraflags); }
void result_line::result_lineSetHWND(HWND rwnd) { rwnd = rwnd; }
void result_line::result_lineSetFlags(int result_flags) { result_flags = result_flags; }
void result_line::result_lineSetExtraFlags(int result_extraflags) { result_extraflags = result_extraflags; }
void result_line::result_lineSetBothFlags(int result_flags, int result_extraflags) {
result_flags = result_flags;
result_extraflags = result_extraflags;
}
void result_line::result_lineSetBothFlags(DINT dint) {
result_flags = dint.aint;
result_extraflags = dint.bint;
}
rsltline
class rsltline {
private:
HWND rlHWND;
int rlflag1;
int rlflag2;
public:
rsltline(HWND, int, int);
HWND rsltlineGetHWND();
int rsltlineGetFlag1();
int rsltlineGetFlag2();
};
rsltline::rsltline(HWND hwnd, int rf1, int rf2) {
rlHWND = hwnd;
rlflag1 = rf1;
rlflag2 = rf2;
}
HWND rsltline::rsltlineGetHWND() { return rlHWND; }
int rsltline::rsltlineGetFlag1() { return rlflag1; }
int rsltline::rsltlineGetFlag2() { return rlflag2; }
I have the following code to create and then display instances using the two classes (the last using the rsltline class as opposed to the result_line class, as used by the first two) :-
result_line foo = result_line(0,3,6);
std::cout << "HWND=" << foo.result_lineGetHWND() <<
"\tFLAGS=" << foo.result_lineGetFlags() <<
"\tEXTRAFLAGS=" << foo.result_lineGetExtraFlags() <<
std::endl;
result_line testrslt = result_line((HWND) 0,100,200);
std::cout << "HWND=" << testrslt.result_lineGetHWND() <<
"\tFLAGS=" << testrslt.result_lineGetFlags() <<
"\tEXTRAFLAGS=" << testrslt.result_lineGetExtraFlags() <<
std::endl;
rsltline myrsltline = rsltline((HWND)2,4,6);
std::cout << "HWND=" << myrsltline.rsltlineGetHWND() <<
"\tFLAGS=" << myrsltline.rsltlineGetFlag1() <<
"\tEXTRAFLAGS=" << myrsltline.rsltlineGetFlag2() <<
std::endl;
The first two return Unexpected Results, the last using the rsltline class works as expected. The results are:-
HWND=0 FLAGS=0 EXTRAFLAGS=0
HWND=0 FLAGS=1997196755 EXTRAFLAGS=0
HWND=0x2 FLAGS=4 EXTRAFLAGS=6
Process returned 0 (0x0) execution time : 35.007 s Press any key to
continue.
The only thing that I can think that may be causing this is the naming of the former. Although, perhaps it's simply a case of me needing to visit an optician :).
Lets take a closer look at the result_line constructor:
// Constructor for result_line(HWND) and result_line(HWND, result_flag)
result_line::result_line(HWND rwnd, int result_flags, int result_extraflags) {
rwnd = rwnd;
result_flags = 30;
result_extraflags = 40;
}
You declare a set of arguments, named rwnd, result_flags and result_extraflags. These are the same a local variables inside the constructor function body, and therefore shadows the member variables with the same name.
What happens is that you assign values to the local variables (the arguments), and not the member variables.
There are three solutions: Either use different names for the arguments, or prefix the member variables with this->, or use a constructor initializer list:
result_line::result_line(HWND rwnd, int result_flags, int result_extraflags)
: rwnd{rwnd}, result_flags{30], result_extraflags{40}
{
// Empty body
}
In the constructor body of result_line, you have written this:
rwnd = rwnd;
which is self-assignment of the parameter. The member remains uninitialized (like the other two members as well). You wanted to write this:
this->rwnd = rwnd;
That is one problem I can see in your code, which can be fixed as above — however, it is best to use member-initialization-list:
result_line::result_line(HWND rwnd, int result_flags, int result_extraflags)
: rwnd(rwnd),
result_flags(result_flags),
result_extraflags(result_extraflags)
{
}
Here, members are initialized in the form of X(Y) — X is a member and Y is a parameter; X and Y could be the same name, but they would continue to represent what they are — member and parameter.
Sorry guys I'm new to C++ and I have this silly question to ask. how to I retrieve the value of civIndex from LocationData computeCivIndex function to PointTwoD class. does the GET function help in this situation?
LocationData.h
class LocationData
{
private:
string sunType;
int noOfEarthLikePlanets, noOfEarthLikeMoons;
float aveParticulateDensity, avePlasmaDensity;
static float civIndex;
public:
LocationData(); //default constructor
LocationData(string, int, int, float, float); // no default constructor
void setLocationData(string, int, int, float, float);
void displaydata();
static float computeCivIndex(string st, int earth, int moons, float particle, float plasma);
};
locationdataimp.cpp
float LocationData::civIndex = 0;
//convert sunType to sunTypePercentage
float LocationData::computeCivIndex(string st, int earth, int moons, float particle, float plasma)
{
float sunTypePercent;
if(st == "Type 0")
{
sunTypePercent = 80.0;
}
else if(st == "Type B")
{
sunTypePercent = 45.0;
}
else if(st == "Type A")
{
sunTypePercent = 60.0;
}
else if(st == "Type F")
{
sunTypePercent = 75.0;
}
else if(st == "Type G")
{
sunTypePercent = 90.0;
}
else if(st == "Type K")
{
sunTypePercent = 80.0;
}
else if(st == "Type M")
{
sunTypePercent = 70.0;
}
// calculate CIV Value
float civNum,civNum1,civNum2,civNum3,civNum4,civNum5;
civNum1 = sunTypePercent / 100;
civNum2 = plasma + particle;
civNum3 = civNum2 / 200;
civNum4 = civNum1 - civNum3;
civNum5 = earth + moons;
civNum = civNum4 * civNum5;
civIndex = civNum;
//return civNum;
}
pointtwod.h file
class PointTwoD
{
private:
int xcord,ycord;
float civIndex;
LocationData locationdata;
public:
PointTwoD();
PointTwoD(int, int, string, int, int, float, float, float);
string toString();
void displayPointdata();
};
pointtwod.cpp
void PointTwoD::displayPointdata()
{
PointTwoD pointtwod;
LocationData locationdata;
cout << "X axis: " << xcord << endl;
cout << "Y axis: " << ycord << endl;
cout << "civ: " << locationdata.civIndex << endl;
//locationdata.displaydata();
}
so what should i include or what mistake have i made?
The declaration of static float LocationData::civIndex; means that civIndex is static and private(*) in LocationData.
(*) as the default access modifier
The private access means that you cannot access it directly via a variable of type LocationData if that class does not explicitly allow it. You have two options:
1) Provide a public getter function:
public static float LocationData::getCivIndex()
{
return civIndex;
}
Note: you will need to declare this function in the class definition as well:
class LocationData
{
// ...
public static float getCivIndex();
};
2) Make the access of civIndex in LocationData public.
The second option is not advised as that would allow any code to directly access and modify the value of civIndex, which can easily lead to errors (and errors of these types are hard to track down in a large project). Even if you need a setter function that only sets the passed-in value, it is advisable to declare the variable private as that forces other code to go through the public method, making it easier to identify what code is accessing the variable during debugging in case of an error.
You can use option 1) like this:
LocationData locationData;
locationdata.getCivIndex();
Or even without having a variable of type LocationData, as the variable is static in that class:
LocationData::getCivIndex();
computeCivIndex is a static member, so the correct syntax is:
cout << "civ: " << LocationData::civindex << endl;
However, your civindex variable is private, so you have to create a getter:
static float getCivIndex()
{
return civIndex;
}
cout << "civ: " << LocationData::getCivIndex() << endl;
You can not directly access locationdata.civIndex like you did. Why? Because you set civIndex as a private member of the LocationData class.
There are a few solutions depending on your needs:
Make civIndex a public member of LocationData
or
Create a getter method to provide civIndex such as
static float getCivIndex( )
{
return civIndex;
}
See:
C++ Public
C++ Protected
C++ Private
In C++ I have an array of doubles which need initialising programmatically, at run time, just once, for the whole class to share. They could be both static and constant. How best can I initialise them? I have gone off using static with the prodigious popularity of parrallel processors presently pervading. So must I set a flag to run once or is there some static const magic which will initialise them as a variable local to a function (ok) or class (ok too)?
double sumOfWeights = 0.0;
double fracObs = 0.0;
for (int i = 0; i < NUMTRACES; i++) {
double weightAtI = SQUARED(1 - SQUARED(MAXTRACEWRTMIDTRACE * (MIDTRACE - i)
/ double(MIDTRACE)));
sumOfWeights += weightAtI;
fracObs += obsArray[i] * weightAtI;
}
return fracObs / sumOfWeights;
In the code above I'd like to make weightAtI a lookup with each double already divided by sumOfWeights so I can retrieve them without iterating through NUMTRACES.
_EDIT_
It's okay, that's what constructors are for :)
Just hoping to tackle my static, const and initialization gremlins into the bargain. Thanks Seth
_EDIT_
Not sure it is quite the effect I wanted though. The constructor runs on each instance, even if the members are static, no? No. Lemme see...
_EDIT_
I think the most efficient solution, is to guard the initializer loop with a static flag, in the constructor. Being a POD flag I'm sure it should behave appropriately, I'm just not quite sure what that is at this stage.
_EDIT_
Ahh, got it:
class X
{
public:
static int i;
};
int X::i = 0; // definition outside class declaration
_EDIT_
Unfortunately, when it comes to my code,
static const int MIDTRACE = 3;
static const int NUMTRACES = 2 * MIDTRACE + 1;
static double WEIGHTATI[NUMTRACES];
I get linker errors:
meobj.obj : error LNK2020: unresolved token (0A00001C) "private: static double * mens:meclass::PIMPL::WEIGHTATI" (?WEIGHTATI#PIMPL#meclass#mens##$$Q0PANA)
meobj.obj : error LNK2001: unresolved external symbol "private: static double * mens:meclass::PIMPL::WEIGHTATI" (?WEIGHTATI#PIMPL#meclass#mens##$$Q0PANA)
due to my constructor:
meclass::PIMPL() {
if (!doneStaticInit) {
double sumOfWeights = 0.0;
for (int i = 0; i < NUMTRACES; i++) {
WEIGHTATI[i] = SQUARED(1 - SQUARED(MAXTRACEWRTMIDTRACE * (MIDTRACE - i) / double(MIDTRACE)));
sumOfWeights += WEIGHTATI[i];
}
for (int i = 0; i < NUMTRACES; i++) WEIGHTATI[i] /= sumOfWeights;
doneStaticInit = true;
}
}
Initialization => constructor. Once => static instance. So one way is static instance of something with constructor.
#include <iostream>
struct Foo
{
Foo()
{
std::cout << "Initializing them values..." << std::endl;
for( int i = 0; i < 3; ++i )
{
values[i] = i;
}
};
int values[3];
};
void doThings()
{
static Foo const foo; // Is initialized ONCE.
for( int i = 0; i < 3; ++i )
{
std::cout << foo.values[i] << " ";
}
std::cout << std::endl;
}
int main()
{
doThings();
doThings();
doThings();
}
Cheers & hth.,
You can put a static bool flag in your constructor. The flag will only be initialized to false the first time it is called. After that it will remain true.
// foo.h
class Foo {
static const int MIDTRACE = 3; // static const, no definition needed
static const int NUMTRACES = 2 * MIDTRACE + 1; // static const, no definition needed
static double WEIGHTATI[NUMTRACES]; // not const, so need definition outside of class
public:
Foo() {
static bool array_initialized = false;
if( !array_initialized ) {
// Initialize array
array_initialized = true;
}
}
// Other members
};
In a source file, not header file:
// foo.cpp
include "foo.h"
double Foo::WEIGHTATI[NUMTRACES];
class Foo {
public:
Foo() { do_something = &Foo::func_x; }
int (Foo::*do_something)(int); // function pointer to class member function
void setFunc(bool e) { do_something = e ? &Foo::func_x : &Foo::func_y; }
private:
int func_x(int m) { return m *= 5; }
int func_y(int n) { return n *= 6; }
};
int
main()
{
Foo f;
f.setFunc(false);
return (f.*do_something)(5); // <- Not ok. Compile error.
}
How can I get this to work?
class A{
public:
typedef int (A::*method)();
method p;
A(){
p = &A::foo;
(this->*p)(); // <- trick 1, inner call
}
int foo(){
printf("foo\n");
return 0;
}
};
void main()
{
A a;
(a.*a.p)(); // <- trick 2, outer call
}
The line you want is
return (f.*f.do_something)(5);
(That compiles -- I've tried it)
"*f.do_something" refers to the pointer itself --- "f" tells us where to get the do_something value from. But we still need to give an object that will be the this pointer when we call the function. That's why we need the "f." prefix.
class A {
int var;
int var2;
public:
void setVar(int v);
int getVar();
void setVar2(int v);
int getVar2();
typedef int (A::*_fVar)();
_fVar fvar;
void setFvar(_fVar afvar) { fvar = afvar; }
void insideCall() { (this->*fvar)(); }
};
void A::setVar(int v)
{
var = v;
}
int A::getVar()
{
std::cout << "A::getVar() is called. var = " << var << std::endl;
return var;
}
void A::setVar2(int v2)
{
var2 = v2;
}
int A::getVar2()
{
std::cout << "A::getVar2() is called. var2 = " << var2 << std::endl;
return var2;
}
int main()
{
A a;
a.setVar(3);
a.setVar2(5);
// a.fvar = &A::getVar;
a.setFvar(&A::getVar);
(a.*a.fvar)();
a.setFvar(&A::getVar2);
(a.*a.fvar)();
a.setFvar(&A::getVar);
a.insideCall();
a.setFvar(&A::getVar2);
a.insideCall();
return 0;
}
I extended Nick Dandoulakis's answer. Thank you.
I added a function which set the member function pointer from outside of the class. I added another function which can be called from outside to show inner call of member function pointer.
Try (f.*do_something)(5);
#include<iostream>
using namespace std;
class A {
public:
void hello()
{
cout << "hello" << endl;
};
int x = 0;
};
void main(void)
{
//pointer
A * a = new A;
void(A::*pfun)() = &A::hello;
int A::*v1 = &A::x;
(a->*pfun)();
a->*v1 = 100;
cout << a->*v1 << endl << endl;
//-----------------------------
A b;
void(A::*fun)() = &A::hello;
int A::*v2 = &A::x;
(b.*fun)();
b.*v2 = 200;
cout << b.*v2 << endl;
}
I think calling a non static member of the class could also be done using a static member function.