I am trying t understand the Named Constructor Idiom in the example I have
Point.h
class Point
{
public:
static Point rectangular(float x, float y);
private:
Point(float x, float y);
float x_, y_;
};
inline Point::Point(float x, float y) : x_(x), y_(y) {}
inline Point Point::rectangular(float x, float y) {return Point(x,y);}
main.cpp
#include <iostream>
#include "include\Point.h"
using namespace std;
int main()
{
Point p1 = Point::rectangular(2,3.1);
return 0;
}
It does not compile If Point::rectangular is not static and I don't understand why...
In this context, the static keyword in front of a function means that this function does not belong to any particular instance of the class. Normal class methods have an implicit this parameter that allow you to access the members of that specific object. However static member functions do not have the implicit this parameter. Essentially, a static functions is the same as a free function, except it has access to the protected and private members of the class it is declared in.
This means you can call static functions without an instance of that class. Instead of needing something like
Point p1;
p1.foo();
You simply do this:
Point::foo();
If you tried to call a non static function like this, the compiler will complain, because non-static functions need some value to assign to the implicit this parameter, and Point::foo() doesn't supply such a value.
Now the reason you want rectangular(int, int) to be static is because it is used for constructing a new Point object from scratch. You do not not need an existing Point object to construct the new point so it makes sense to declare the function static.
Related
I have a silly question:
I have a class and in one of its methods I have to do some calculations and I need to declare some variables that are useful to do this. For example:
class Percettrone {
public:
Percettrone(double NL);
void fit(double X, double y);
}
.
.
.
void Percettrone::fit(double X, double y)
{
double delta[50][50];
double conteggio=0;
//calculations
}
Is it correct? Or is it better to declare when I create the class? Moreover I have to call this method lots of time during my programme
If those variables are affecting the object instance and identifying its state, then you must declare them in the class as attributes. On the other hand, if they're just helper variables in the function, and you don't need to use them anywhere else, then make them local inside the function as you did in the example.
The assignment is to create a constant function getArea() that returns the area of a rectangle.
double getArea() {
return width * height;
}
Is this it?
Do I put const after the parameters?
I don't really understand what I'm being asked.
In C++, a function becomes const when const keyword is used in function’s declaration. The idea of const functions is not allow them to modify the object on which they are called.
double getArea() const {
return width * height;
}
const after the (empty) argument list in the function declarations. indicates that getArea() function do not modify the state of a object i.e. data member of a object.
Please refer this link for more explanation: http://www.codeproject.com/Articles/389602/Constant-Member-Functions-Are-Not-Always-Constant
double getArea() const
{
return width * height;
}
const keyword is used when the user doesnt want to modify or change the values of that variable or function.
Just like the built-in data types (int, double, char, etc…), class objects can be made const by using the const keyword. All const variables must be initialized at time of creation.
Once a const class object has been initialized via constructor, any attempt to modify the member variables of the object is disallowed, as it would violate the constness of the object. This includes both changing member variables directly (if they are public), or calling member functions that sets the value of member variables.
const class objects can only call const member functions. A const member function is a member function that guarantees it will not change any class variables or call any non-const member functions.
SOURCE : leancpp.com
Consider:
class ClassType
{
int x;
public:
ClassType(int _x) : x(_x) {}
int GetX() { return x;}
};
const ClassType object(20);
object.GetX();
This will fail to compile, since the object is const (readonly). But GetX is not marked const (readonly). length(), size(), IsOpen() are example of methods that may be called from a read only object. Hence the class should facilitate such (const) functions for const object.
You generally don't create const object, but you do pass them like:
void foo(const ClassType& obj);
Therefore, the GetX function should be:
int GetX() const { return x;}
const make a promise or a contract that this function doesn't modify this object.
in C# I created a static class which had a number of mathematical helper functions I could call directly without creating an instance of the class. I cannot seem to get this to work in C++.
For example, if the class is called MathsClass and has a function called MultiplyByThree then I would use it like this:
float Variable1 = MathsClass.MultiplyByThree(Variable1);
In the C++ version of my code I am getting the errors:
'MathsClass' : illegal use of this type as an expression
and
error C2228: left of '.MultiplyByThree' must have class/struct/union
How would I write the C++ equivalent of the C# static class to give this kind of functionality?
The easy answer is to use the :: operator instead of the . operator:
float Variable1 = MathsClass::MultiplyByThree(Variable1);
But in C++, free functions are generally preferred over static class functions, unless you have a specific reason to put them in a class. For keeping them together, and not polluting the global namespace, you can put them in their own namespace:
In Math.h
namespace Math
{
float MultiplyByThree(float x);
}
In Math.cpp:
#include "math.h"
namespace Math
{
float MultiplyByThree(float x)
{
return x * 3;
}
}
And to use it:
#include "math.h"
float Variable1 = Math::MultiplyByThree(Variable1);
Even better, make it a template and the same code will work for floats, doubles, ints, complex, or any type that has operator* defined:
In Math.h
namespace Math
{
template <typename T>
T MultiplyByThree(T x)
{
return x * 3;
}
}
The only issue being that you can't separate the definition into math.cpp, it has to be in the header.
Use :: in place of .:
float Variable1 = MathsClass::MultiplyByThree(Variable1);
Also, make sure MultiplyByThree is declared static:
class MathsClass {
...
public:
static float MultiplyByThree(float arg);
...
}
Lastly, if the class consists entirely of static helper functions, you might want to prohibit the creation of instances of MathsClass by making its constructor private.
The . operator only works on objects. The :: operator (Scope Resolution Operator) is used to access the members of a scope, in the sense of a namespace or type. The exact equivalent is like so:
class MathsClass
{
static float MultiplyByThree(const float Value);
};
Calling it like so:
float TwoTimesThree = MathsClass::MultiplyByThree(2.0f);
I would not advise this however. Use a namespace instead. Does it make sense to allow the user to make a MathsClass object? If not, then simply make it a namespace. The syntax for calling the function remains the same.
namespace Maths
{
float MultiplyByThree(const float Value);
}
float TwoTimesThree = Maths::MultiplyByThree(2.0f);
You can define Maths::MultiplyByThree in the header if you want it inlined (or attempt to inline it), but otherwise, you should define it separately in a ".CPP" file. In the ".CPP" file, you can either define it like this:
namespace Maths
{
float MultiplyByThree(const float Value)
{
// Definition here.
}
}
... or like this:
float Maths::MultiplyByThree(const float Value)
{
// Definition here.
}
Assuming that MultiplyByThree is a static method, you should call it as:
float var1 = MathsClass::MultiplyByThree(varx);
Usually, standalone functions will go in a namespace rather than a class:
namespace Maths {
template <typename T> T MultiplyByThree(T const & x) {return x * 3;}
}
You then use the scope-resolution operator to access the function: Maths::MultiplyByThree
If for some reason you really want to make it a static member of a class, then the syntax is the same: static members can be accessed as either class_name::member or object.member, but not as class_name.member.
Make all members of your class static and call them with the :: syntax.
The purpose of a C# static class is to prevent instantiation, so you should also make your MathsClass() constructor in the private section of your interface to prevent instantiation from ever occurring :)
I don't get all these keywords. Specially this one static. An example of how important it is and how it used would be wonderful.
Making a member function static allows you to call the function without creating the class object.
class MyClass
{
int i;
static MyClass *ptr;
static MyClass* getInstance()
{
if(NULL == ptr)
{
ptr = new MyClass();
}
return ptr;
}
};
MyClass* MyClass::ptr = NULL;
int main()
{
MyClass *ptr = MyClass::getInstance();
}
Check out the Singleton pattern for more information on how it can be helpful.
static member functions are just like regular functions.
class Sample
{
public:
static void DoWork()
{
cout << "Static Member Function"<< endl;
}
};
//access
Sample::DoWork();
Output:
Static Member Function
You can treat them just like regular functions, that means, you can pass them to other functions which accept only regular function as argument, like this:
typedef void (*Worker)();
void Fun(Worker worker)
{
//call here just like regular function
worker(); //note: class name is not needed even if you pass static member function!
}
//pass static member function!!
Fun(Sample::DoWork);
Output:
Static Member Function
There are multiple uses for the static keyword, it does different things based on where you use it.
http://msdn.microsoft.com/en-us/library/s1sb61xd.aspx
When you declare a variable or
function at file scope (global and/or
namespace scope), the static keyword
specifies that the variable or
function has internal linkage. When
you declare a variable, the variable
has static duration and the compiler
initializes it to 0 unless you specify
another value.
When you declare a variable in a
function, the static keyword specifies
that the variable retains its state
between calls to that function.
When you declare a data member in a
class declaration, the static keyword
specifies that one copy of the member
is shared by all instances of the
class. A static data member must be
defined at file scope. An integral
data member that you declare as const
static can have an initializer.
When you declare a member function in
a class declaration, the static
keyword specifies that the function is
shared by all instances of the class.
A static member function cannot access
an instance member because the
function does not have an implicit
this pointer. To access an instance
member, declare the function with a
parameter that is an instance pointer
or reference.
Static classes and class members are used to create data and functions that can be accessed without creating an instance of the class. The advantage is that you don't need to instantiate the class to use methods or properties.
An example of when to use a static class might be for utility functions such as converters (e.g. Fahrenheit to Celcius). This type function doesn't change irregardless of any object or data.
In C# you can call a static method like this:
double F, C = 0
// TempConverter converter = new TempConverter(); <-- NOT NEEDED FOR STATIC
F = TempConverter.CelsiusToFahrenheit("100.0");
C = TempConverter.FahrenheitToCelcius("212.0");
Here is how the static class and methods are defined:
public static class TemperatureConverter {
public static double CelsiusToFahrenheit(string temperatureCelsius) {
.. conversion code..
}
public static double FahrenheitToCelsius(string temperatureFahrenheit) {
.. conversion code..
}
}
There are two types of static functions: class/struct member, and non-member. I guess you're wondering about the former (as it's more confusing)...
static member functions
If we contrast four functions:
class X
{
....
int non_static_member_f(X& a) { ... }
static int static_member_f(X& a) { ... }
friend int non_member_friend_f(X& a) { ... }
};
int non_member_f(X& a) { ... }
And given:
X x, arg;
We can write:
x.non_static_member_f(arg) - x is an existing X object instance - made accessible via the this pointer. The function has full access to all private/protected/public static/non-static members of X for operations on x and arg.
X::static_member_f(arg) can be invoked with a single X argument - if the function didn't specify an X argument, then it could be called with no existing X objects. It has full access to all private/protected/public static of X, and can access any non-static members on arg.
non_member_friend_f(arg) has the same access as X::static_member_f(arg), but is not scoped inside X (i.e. you don't need to call it with the X:: prefix, Koenig lookup resolves differently).
non_member_f(arg) can only access the public members of arg, and has no special privileges.
For completeness: static non-member functions differ from non-static in having internal linkage, which means they're not callable from other translation units but won't clash with any same-named function in those translation units.
Static functions are very useful when implementing so-called Named Constructors.
Imagine a Point class which can be either constructed from rectangular coordinates (X/Y) or polar coordinates (radius and angle):
class Point {
public:
Point(float x, float y); // Rectangular coordinates
Point(float r, float a); // Polar coordinates (radius and angle)
// ERROR: Overload is Ambiguous: Point::Point(float,float)
};
int main()
{
Point p = Point(5.7, 1.2); // Ambiguous: Which coordinate system?
...
}
This can be solved very nicely using static functions which create Point objects; such functions are called named constructors since they act like a constructor (they produce a new object) but they can have a descriptive name:
class Point {
public:
// These static methods are the so-called "named constructors"
static Point rectangular(float x, float y) { return Point(x, y); }
static Point polar(float radius, float angle) { return Point(radius*std::cos(angle), radius*std::sin(angle)); }
// ...
private:
Point(float x, float y) : x_(x), y_(y) { }
float x_, y_;
};
Clients of the class can now use these named constructors to create readable, unambiguous code:
int main()
{
Point p1 = Point::rectangular(5.7, 1.2); // Obviously rectangular
Point p2 = Point::polar(5.7, 1.2); // Obviously polar
}
Furthremore, named constructors can be used to make sure that objects of a class are always allocated with new (so that you know that you can always call delete on them). See FAQ [16.21] for more information.
static class member functions are useful:
For implementing the Factory Method Pattern
For implementing the Singleton Pattern
For loose decoupling of functions that may polute the behaviour of the class. ( Functions not necessarily members can be declared static... but even better they could be totally classic functions!) cf S.R.P.
Can be used as a function to be passed as a plain C function pointer so as to inter-operate with C code...
static functions are useful:
1. to avoid duplicate code redefinition while compiling. A static function will be redefined for each cpp unit it is included in.
And I think there are tons of other useful cases I don't remember of right now :-)
The answer from martona is a good overview of static. Relating to static members, I think Tony covers it pretty well.
The mental model I use when it comes to member functions is to consider how they might be modeled in 'C':
class A
{
public:
void mbr_1 ();
void mbr_2 () const;
void mbr_3 () volatile;
void mbr_4 () const volatile;
static void mbr_5 ();
};
Might be implemented as:
struct A { };
void mbr_1 (A * const this);
void mbr_2 (A const * const this);
void mbr_3 (A volatile * const this);
void mbr_4 (A const volatile * const this);
void mbr_5 ();
All the funcitons are members and so have appropriate 'access' to private members. The non static members have a 'this' pointer, and it is that which provides the access to a specific instances members. The static member doesn't have such a pointer and this is why we cannot access any non static members.
I'm developing a game which is based around the user controlling a ball which moves between areas on the screen. The 'map' for the screen is defined in the file ThreeDCubeGame.cpp:
char m_acMapData[MAP_WIDTH][MAP_HEIGHT];
The ThreeDCubeGame.cpp handles most of the stuff to do with the map, but the player (and keyboard input) is controlled by ThreeDCubePlayer.cpp. When a player moves into a new map cell, the game will have to check the contents of that cell and act accordingly. This function in ThreeDCubeGame.cpp is what I am trying to use:
inline char GetMapEntry( int iMapX, int iMapY ) { return m_acMapData[iMapX][iMapY]; }
So, in order to check whether the player is allowed to move into a map cell I use this function call from ThreeDCubePlayer.cpp:
if (ThreeDCubeGame::GetMapEntry(m_iMapX+MAP_OFF_X, m_iMapY+MAP_OFF_Y) == ' ')
{
// do stuff
}
But, when I compile this, I get the warning "error C2352: 'ThreeDCubeGame::GetMapEntry' : illegal call of non-static member function". Is this something to do with the scope of the variables? Is it fixable without redesigning all the code?
class A {
int i;
public:
A(): i(0) {}
int get() const { return i; }
};
int main() {
A a;
a.get(); // works
A::get(); // error C2352
}
There's no object to call the function with.
GetMapEntry is not static so you can't call it without an object of the type ThreeDCubeGame.
Alternatives:
-Make GetMapEntry static: static inline char GetMapEntry
-Create an instance of ThreeDCubeGame and do instance.GetMapEntry(
ThreeDCubeGame is a class, not an instance, thus you can only use it to access static members (that is, member function with the keyword static)
You have to instantiate an object of this class to use non-static members
ThreeDCubeGame map;
...
map.GetMapEntry(iMapX, iMapY).
You are trying to call a class method. Is that what you intend? Or do you mean for GetMapEntry to be an instance method? If it's a class method, it needs to be marked static. If it's an instance method, you need to call it with an instance of ThreeDCubeGame. Also, is GetMapEntry even a member of a class?
The error indicates that your are calling the GetMapEntry function as a static one whereas you have declare it as a member function. You need to:
call it via an instance of ThreeDCubeGame: threedcubegameinstance.GetMapEntry(),
declare the GetMapEntry function as static (add a static before inline and make m_acMapData static too).
You're missing the "static" keyword.
// .h
class Playfield
{
public:
static char GetTile( int x, int y );
// static on a method means no 'this' is involved
};
// .cpp
static char tiles[10][10] = {};
// static on vars in .cpp prevents access from outside this .cpp
char Playfield::GetTile( int x, int y )
{
// handle invalid args
// return tile
return tiles[x][y];
}
There's other options if you want only one unique playfield:
You can make Playfield a singleton, turn it into a namespace or use global functions.
The result is the same from the caller's point of view.
On a side note:
Since all of these use a static and/or global variable it's inherently not thread-safe.
If you require multiple playfields and/or want to play safe with multi-threadding and/or want to absolutely do it in an OOP fashion, you will need an instance of Playfield to call the function on (the 'this' pointer):
class Playfield
{
public:
char GetTile( int x, int y ) const { return this->tiles[x][y]; }
// you can omit 'this->', but it's inherently present because
// the method is not marked as static
public:
Playfield()
{ /*you will have to initialize 'this->tiles' here because
you cannot use the struct initializer '= {}' on member vars*/ }
private:
char tiles[10][10];
};
The calling code would use Playfield like this:
void main()
{
// static version
char tile11 = Playfield::GetTile( 1, 1 );
// non-static version
Playfield myPlayfield;
char tile12 = myPlayfield.GetTile( 1, 2 );
}
It can be useful to have a class containing a collection of functions, without any data members, if you don't want to expose the helper-functions.
Otherwise it would be more practical to use a namespace to collect these functions in.
Example:
class Solvers
{
public:
void solve_a(std::vector<int> data);
void solve_b(std::vector<int> data, int value);
private:
int helper_a(int a, int b);
}
But a class needs to be initialised before use.
The simplest way to make these functions usable would be to mark them static in the class:
static void solve_a(std::vector<int> data);
Then the member-functions can be used as:
Solver::solve_a(my_vector);
Another way would be to initialise the class before using:
Solver solver;
solver.solve_a(my_vector);
And the third method, not mentioned before, is by default initialising it during use:
Solver().solve_a(my_vector);