I am trying to run a simple C++ program. Whenever I run the code I get the same output 'error: passing 'cont Point' as 'this' argument discards qualifiers [-fpermissive]'. The problem seems to be occurring whenever I call the set function. I am still new to C++ and am still trying to get familiar with its functions so I apologize if the answer may seem obvious. Below is the code that is giving me problems:
#include <QTextStream>
#include <QString>
class Point {
public:
Point(int px, int py)
: m_X(px), m_Y(py) {}
void set(int nx, int ny) {
m_X = nx;
m_Y = ny;
}
QString toString() const {
// m_X = 5;
m_Count++;
return QString("[%1,%2]").arg(m_X).arg(m_Y);
}
private:
int m_X, m_Y;
mutable int m_Count;
};
int main() {
QTextStream cout(stdout);
const Point p(1,1);
const Point q(2,2);
p.set(4,4);
cout << p.toString() << endl;
q.set(4,4);
return 0;
}
In C++, you cannot modify an object marked as const, which is a keyword used in C++, a synonym of "non-modifiable", used to tell the compiler that a variable cannot be modified. In your main,
const Point p(1,1);
const Point q(2,2);
p.set(4,4);
q.set(4,4);
the variables p and q are of type const Point but the member function Point::set is not marked const. Since the member function Point::set is not a const member function of class Point, the compiler thinks the function tries to modify the object it is called on (in the statement p.set(4,4); the function set tries to modify p), but this is not allowed since you marked p (and q) to be const, recall, "non-modifiable".
Now, notice that you could mark member function Point::set as const, but that would be nonsensical since you want to modify the variables (in this case p and q). A solution would be to drop the const qualifier from p and q.
You can watch this video to learn about const member functions; you can also watch this video to learn more about member functions in C++.
Related
Visual studio shows a error saying "the object has type quantifiers that are not compatible with the member function 'somfunc' "
class T_ship {
public:
...
float ship_run(int ship_len);
// function ship_run doesn't change any class member values
};
There is a function in main() with *T_ship pointer passed as input.
void draw_ship(const T_ship * a_shp){
float dist = a_ship-> ship_run(100);
// there is a red wavy line under a_ship
}
Many thanks if someone can help.
If you want the actual pointer to be const and not the object pointed to, put the const in front of the type, so like this:
T_ship * const
However in your case if the function ship_run doesn't modify anything you should
mark it as const at the end of the function as well so like this:
float ship_run(int v) const { /* your code here */ }
I am new to C++. I have this code to create a struct, to show the usage of mutable keyword in C++.
#include <iostream>
using namespace std;
int main()
{
struct
{
mutable double radius;
double PI = 3.142;
double getArea()
{
return (PI * radius * radius);
}
} circle;
const struct circle c1 = {2.0};
circle.radius = 7;
cout << "Area is " << circle.getArea() << endl;
return 0;
}
But I get the following error message when compiling:
error: variable const main()::circle c1 has initializer but incomplete type
Error is at c1 in the line const struct circle c1 = {2.0};. Can anyone point me out the error here.
You don't define a structure named circle, you define a variable named circle. This variable can not be used as a type.
You should do e.g. struct circle { ... }; to define the structure as a type. Then you could do
const circle c1 = { 2.0 };
c1.radius = 7;
std::cout << c1.getArea() << '\n';
There are a few other problems, most notable you don't declare the getArea function as const which means you can't call it on const objects.
When you put the name circle after the right brace at the end of the struct definition, you're declaring a variable.
Put it at the start, after the word struct, to declare a type.
I.e.
struct circle
{
// ...
};
In other news:
You'll need to declare getArea() as const to be able to call it on a const instance, i.e. double getArea() const.
You don't need the return 0; at the end, because that's the default for main. There is no such default for other functions. main is special.
In order to use cout unqualified (as it seems you want to) you can add using namespace std; at the start of the code; it's usually placed after the includes.
mutable is usually not used to allow outside code to treat part of an object as always non-const.
Instead it's used as a device to more easily let a class implementation have some non-const state also when the object appears to be const to outside code. That's called logical constness. For example, the object might cache the result of an expensive computation, even when it's const.
In C++17 and later mutable can also be applied to lambda expressions, where it yields a lambda that can change its state (captured values).
For a homework assignment we are asked to create two classes: a MyPoint class and a ThreeDPoint class.
Here is my MyPoint class:
#pragma once
#include <math.h>
class MyPoint
{
private:
double x, y;
public:
MyPoint()
{
x = y = 0;
}
MyPoint(double x, double y)
{
this->x = x;
this->y = y;
}
double getX()
{
return x;
}
double getY()
{
return y;
}
double distance(MyPoint pointB)
{
return sqrt((x - pointB.x) * (x - pointB.x)
+ (y - pointB.y) * (y - pointB.y));
}
};
Here is my ThreeDPoint class:
#pragma once
#include "MyPoint.h"
class ThreeDPoint : public MyPoint
{
private:
double z;
public:
ThreeDPoint() // : MyPoint()
{
z = 0;
}
ThreeDPoint(double x, double y, double z) : MyPoint(x, y)
{
this->z = z;
}
double getZ()
{
return z;
}
double distance(ThreeDPoint pointB) // function overloading
{
// x and y are private not protected
return sqrt((getX() - pointB.getX()) * (getX() - pointB.getX())
+ (getY() - pointB.getY()) * (getY() - pointB.getY())
+ (getZ() - pointB.getZ()) * (getZ() - pointB.getZ()));
}
};
And here is main:
#include <iostream>
#include "SignatureBlock.h"
#include "MyPoint.h"
#include "ThreeDPoint.h"
int main()
{
SignatureBlock myBlock;
std::cout << myBlock.toString();
MyPoint pointA(1, 2);
MyPoint pointB(4, 2.5);
std::cout << pointA.distance(pointB) << '\n';
ThreeDPoint point_a(0, 0, 0);
ThreeDPoint point_b(10, 30, 25.5);
std::cout << point_a.distance(point_b) << '\n';
return 0;
}
This code works fine. It is able to calculate the distance between two points in both 2-dimensional and 3-dimensional space. However, in the homework instructions for the ThreeDPoint class, the book says to create
"A constant get function that returns the z value"
and
"A constant distance(const MyPoint&) function to return the distance between this point and the other point in three-dimensional space."
My question is what do they mean by "A constant get function..." and "A constant distance(const MyPoint&) function..."? I understand that you can put const after a function declaration to prevent the function from changing any class members, but why is this necessary here?
Also, why would I pass const MyPoint& to the distance function rather than a ThreeDPoint object? After all we're trying to find the distance between two ThreeDPoints. I read that if you have a parent object parameter in the member function declaration any child of that parent can also be passed to the function, so maybe that has something to do with it.
Lastly, isn't the distance(const MyPoint&) in the instructions missing a name for the MyPoint& object? I did try to type this in and the compiler doesn't mind, but how would I access the members of the object being passed in?
Edit: Also, what purpose does the & serve?
Most importantly, how would I re write my code to follow exactly what the instructions state?
Thanks for reading and thank you for any suggestions anyone might have.
If you live in a world where there are no const objects, it's never necessary to mark methods const. However, it is a good idea. Using const pointers and references is a very good practice when you don't need to change members of an object, and it can help you find design flaws when your program gets bigger.
It's also a good practice to pass references to objects, because passing a reference is usually faster than passing a copy of the object. (It's also in this context that you'll use const references: it tells the caller that you want the object by reference because it's faster, not because you want to change it.)
It's legal to omit argument names, but it has the obvious consequence that you won't be able to use them in your function. It's also a common notation because compilers get rid of argument names when they create function signatures, so you'll often see error messages that look like distance(const MyPoint&) instead of distance(const MyPoint& point).
I can't help you about why they want a const MyPoint& for the ThreeDPoint class. My best guess is that they want you to assume the z component of that point is 0.
I'm getting this weird error:
error C2663:
'sf::Drawable::SetPosition' : 2
overloads have no legal conversion for
'this' pointer
I think it has something to do with const mismatches but I don't know where, or why.
In the following code I have a vector of shapes and sprites, and when trying to access one of the vectors shapes and calling one of its functions I'm getting the error.
std::vector<sf::Shape> Shapes;
std::vector<sf::Sprite> Sprites;
bool AddShape(sf::Shape& S){
Shapes.push_back(S); return true;
};
bool AddSprite(sf::Sprite& S){
Sprites.push_back(S); return true;
};
private:
virtual void Render(sf::RenderTarget& target) const {
for(unsigned short I; I<Shapes.size(); I++){
Shapes[I].SetPosition(
Shapes[I].GetPosition().x + GetPosition().x,
Shapes[I].GetPosition().y + GetPosition().y);
target.Draw(Shapes[I]);
}
for(unsigned short I; I<Sprites.size(); I++){
target.Draw(Sprites[I]);
}
}
How can I fix this?
Render is declared with a const after the parameters. This means it does not change its object. Which means, that all of the object's member variables are considered constants within Render, as changing their state means changing the containing object. Assuming Shapes is a member variable, and that SetPosition does change the shape (i.e. not declared as const), you cannot call it within a const member function.
So, remove the const from Render and you'll be fine (you fix your logic, in case it must be const).
Suppose I have a class:
class test {
public:
void print();
private:
int x;
};
void test::print()
{
cout<< this->x;
}
and I have these variable definitions:
test object1;
test object2;
When I call object1.print() this happens to store address of object1 and so I get x from object1 printed and when I call object2.print() this happens to store address of object2 and I get x from object2 printed. How does it happen?
Each non-static member function has an implicit hidden "current object" parameter that is exposed to you as this pointer.
So you can think that for
test::print();
there's some
test_print( test* this );
global function and so when you write
objectX.print();
in your code the compiler inserts a call to
test_print(&objectX);
and this way the member function knows the address of "the current" object.
You can think of the this pointer being an implicit argument to the functions. Imagine a little class like
class C {
public:
C( int x ) : m_x( x ) { }
void increment( int value ) {
m_x += value; // same as 'this->m_x += value'
}
int multiply( int times ) const {
return m_x * times; // same as 'return this->m_x * times;'
}
private:
int m_x;
};
which allows you to write code like
C two( 2 );
two.increment( 2 );
int result = two.multiply( 3 );
Now, what's actually happening is that the member functions increment and multiply are called with an extra pointer argument, pointing to the object on which the function is invoked. This pointer is known as this inside the method. The type of the this pointer is different, depending on whether the method is const (as multiply is) or not (as is the case with increment).
You can do something like it yourself as well, consider:
class C {
public:
C( int x ) : m_x( x ) { }
void increment( C * const that, int value ) {
that->m_x += value;
}
int multiply( C const * const that, int times ) const {
return that->m_x * times;
}
private:
int m_x;
};
you could write code like
C two( 2 );
two.increment( &two, 2 );
int result = two.multiply( &two, 3 );
Notice that the type of the this pointer is C const * const for the multiply function, so both the pointer itself is const but also the object being pointed to! This is why you cannot change member variables inside a const method - the this pointer has a type which forbids it. This could be resolved using the mutable keyword (I don't want to get side-tracked too far, so I'll rather not explain how that works) but even using a const_cast:
int C::multiply( int times ) const {
C * const that = const_cast<C * const>( this );
that->m_x = 0; // evil! Can modify member variable because const'ness was casted away
// ..
}
I'm mentioning this since it demonstrates that this isn't as special a pointer as it may seem, and this particular hack is often a better solution than making a member variable mutable since this hack is local to one function whereas mutable makes the variable mutable for all const methods of the class.
The way to think about it is that this is simply a pointer to the memory for whichever object you're currently working with. So if you do obj1.print(), then this = &obj1;. If you do obj2.print(), then this = &obj2;.
this has different values for different objects
Each instance of class test gets it's own copy of member variable x. Since x is unique for each instance, the value can be anything you want it to be.
The variable this, refers to the instance to which it is associated. You don't have to use the variable 'this'. You could just write:
void test::print()
{
cout << x;
}