Windows.h causes a problem with C++ class - c++

I'm using Visual Studio 2019, and when I made my first class in C++, an error occurred. It dissappeared when I deleted #include <Windows.h>. My question is, why does Windows.h collide with C++ classes, and is it possible to use both (I'm almost sure it is).
#include <iostream>
#include <locale>
using std::cout;
using std::cin;
class Rectangle {
public:
Rectangle() = default;
Rectangle(double width, double height)
: width_{ width }, height_{ height }
{}
double Width() const { return width_; }
double Height() const { return height_; }
double Area() const {
return width_ * height_;
}
double Perimeter() const {
return 2 * (width_ + height_);
}
void Scale(double scaleFactor) {
width_ *= scaleFactor;
height_ *= scaleFactor;
}
private:
double width_{};
double height_{};
};
void printInfo(const Rectangle & r) {
cout << "Width" <<r.Width() << '\n';
cout << "Height" << r.Height() << '\n';
cout << "Area" << r.Area() << '\n';
cout << "Per" << r.Perimeter() << '\n';
}
int main() {
setlocale(LC_ALL, "pl_PL.UTF8");
Rectangle rect;
}

Windows.h defines Rectangle as a free function, see here.
Solution: change the name of your class or put it in its own namespace.

Related

Derived classes' attributes are empty

I am new to C++ and I am currently playing with inheritance. I am creating a base Polygon class that is inherited by Rectangle and Triangle classes respectively. From there I want to print out the area as defined in calcArea. However, the output of my derived class instances seem to be null.
From what I understand the Polygon:(name, width, height) can help to initialize variables that already exist in the base class. Thanks for all the help!
Here's my code:
#include <iostream>
#include <string>
using namespace std;
enum Polytype {POLY_PLAIN, POLY_RECT, POLY_TRIANG};
class Polygon
{
public:
Polygon(string name, double width, double height){
_name = name;
_width = width;
_height = height;
_polytype = POLY_PLAIN;
}
virtual ~Polygon()
{
cout << "Destroying polygon" << endl;
}
virtual Polytype getPolytype(){
return _polytype;
}
virtual void setPolytype(Polytype polytype){
_polytype = polytype;
}
virtual string getName(){
return _name;
}
virtual double calcArea(){
return _width * _height;
}
private:
string _name;
double _width;
double _height;
Polytype _polytype;
};
class Rectangle: public Polygon
{
public:
Rectangle(string name, double width, double height) : Polygon(name, width, height){
_polytype = POLY_RECT;
};
~Rectangle()
{
cout << "Destroying rectangle" << endl;
}
Polytype getPolytype(){
return _polytype;
}
void setPolytype(Polytype polytype){
_polytype = polytype;
}
double calcArea(){
return _width * _height;
}
string getName(){
return _name;
}
private:
string _name;
double _width;
double _height;
Polytype _polytype = POLY_RECT;
};
class Triangle: public Polygon
{
public:
Triangle(string name, double width, double height) : Polygon(name, width, height){
_polytype = POLY_TRIANG;
};
~Triangle()
{
cout << "Destroying triangle" << endl;
}
Polytype getPolytype(){
return _polytype;
}
void setPolytype(Polytype polytype){
_polytype = polytype;
}
string getName(){
return _name;
}
double calcArea(){
return 0.5 * _width * _height;
}
private:
string _name;
double _width;
double _height;
Polytype _polytype;
};
int main(){
//Initialize rectangle and triangle and store them onto the stack
Rectangle rect("RectA", 10.0, 20.0);
Triangle triang("TriangB", 10.0, 20.0);
cout << "Name is " << rect.getName() << endl;
cout << "Name is "<< triang.getName() << endl;
string rectArea = to_string(rect.calcArea());
string triangArea = to_string(triang.calcArea());
cout << "RectA's area is " << rectArea << endl;
cout << "TriangB's area is " << triangArea << endl;
return 0;
}
And here's my output:
Name is
Name is
RectA's area is 0.000000
TriangB's area is 0.000000
Destroying triangle
Destroying polygon
Destroying rectangle
Destroying polygon
The main problem is that you have variables in the sub classes shadowing the names in the base class - so you assign values to the variables in the base class, but you later print the values of the default initialized variables in the sub classes.
You actually mostly need to remove code.
I would rethink the name of the base class though. Polygon is not a good name for a class with only width and height. I'll leave that up to you.
I've replaced all endl with \n. They do the same thing, but endl flushes the output, which is usually not needed - but it is usually also expensive.
Example:
#include <iostream>
#include <string>
enum Polytype { POLY_PLAIN, POLY_RECT, POLY_TRIANG };
class Polygon {
public:
Polygon(std::string name, double width, double height)
: Polygon(name, width, height, POLY_PLAIN) {}
virtual ~Polygon() { std::cout << "Destroying polygon\n"; }
// make member functions that does not change the object `const`:
virtual Polytype getPolytype() const { return _polytype; }
virtual void setPolytype(Polytype polytype) { _polytype = polytype; }
virtual const std::string& getName() const { return _name; }
// in your case, the implementation could actually be in the base class - but
// I've made it into a pure virtual here.
virtual double calcArea() const = 0; // no instances can be made of Polygon
protected:
// only derived classes can access this constructor:
Polygon(std::string name, double width, double height, Polytype ptype)
: _name(name), _width(width), _height(height), _polytype(ptype) {}
std::string _name;
double _width;
double _height;
Polytype _polytype;
};
class Rectangle : public Polygon {
public:
Rectangle(std::string name, double width, double height)
//use the protected base class ctor:
: Polygon(name, width, height, POLY_RECT) {};
~Rectangle() { std::cout << "Destroying rectangle\n"; }
// the only implementation needed in this sub class:
double calcArea() const override { return _width * _height; }
};
class Triangle : public Polygon {
public:
Triangle(std::string name, double width, double height)
: Polygon(name, width, height, POLY_TRIANG) {};
~Triangle() { std::cout << "Destroying triangle\n"; }
// the only implementation needed in this sub class:
double calcArea() const override { return 0.5 * _width * _height; }
};
int main() {
// Initialize rectangle and triangle and store them onto the stack
Rectangle rect("RectA", 10.0, 20.0);
Triangle triang("TriangB", 10.0, 20.0);
std::cout << "Name is " << rect.getName() << '\n';
std::cout << "Name is " << triang.getName() << '\n';
std::cout << "RectA's area is " << rect.calcArea() << '\n';
std::cout << "TriangB's area is " << triang.calcArea() << '\n';
}
I realized that I did not have to redeclare the private variables in my subclasses. That is probably the reason why it returned null.
#include <iostream>
#include <string>
using namespace std;
enum Polytype {POLY_PLAIN, POLY_RECT, POLY_TRIANG};
class Polygon
{
public:
Polygon(string name, double width, double height){
_name = name;
_width = width;
_height = height;
_polytype = POLY_PLAIN;
}
~Polygon()
{
cout << "Destroying polygon" << endl;
}
virtual Polytype getPolytype(){
return _polytype;
}
virtual void setPolytype(Polytype polytype){
_polytype = polytype;
}
virtual string getName(){
return _name;
}
virtual double calcArea(){
return _width * _height;
}
protected:
string _name;
double _width;
double _height;
Polytype _polytype;
};
class Rectangle: public Polygon
{
public:
Rectangle(string name, double width, double height) : Polygon(name, width, height){
_polytype = POLY_RECT;
};
~Rectangle()
{
cout << "Destroying rectangle" << endl;
}
Polytype getPolytype(){
return _polytype;
}
void setPolytype(Polytype polytype){
_polytype = polytype;
}
double calcArea(){
return _width * _height;
}
string getName(){
return _name;
}
};
class Triangle: public Polygon
{
public:
Triangle(string name, double width, double height) : Polygon(name, width, height){
_polytype = POLY_TRIANG;
};
~Triangle()
{
cout << "Destroying triangle" << endl;
}
Polytype getPolytype(){
return _polytype;
}
void setPolytype(Polytype polytype){
_polytype = polytype;
}
string getName(){
return _name;
}
double calcArea(){
return 0.5 * _width * _height;
}
};
int main(){
//Initialize rectangle and triangle and store them onto the stack
Rectangle rect("RectA", 10.0, 20.0);
Triangle triang("TriangB", 10.0, 20.0);
cout << "Name is " << rect.getName() << endl;
cout << "Name is "<< triang.getName() << endl;
string rectArea = to_string(rect.calcArea());
string triangArea = to_string(triang.calcArea());
cout << "RectA's area is " << rectArea << endl;
cout << "TriangB's area is " << triangArea << endl;
return 0;
}

Copy constructor calling the default constructor during delegation instead of the appropriate one [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
So I have the following Box class:
Box.h
#ifndef BOX_H
#define BOX_H
class Box {
private:
double _length {1.0},
_width {1.0},
_height {1.0};
// can be modified in const member functions
mutable unsigned count {};
public:
Box() = default;
Box(double length, double width, double height);
Box(double side);
Box(const Box& box);
double volume() const;
friend double surfaceArea(const Box& aBox);
double& length() { return _length; }
double& width() { return _width; }
double& height() { return _height; }
double length() const { return _length; }
double width() const { return _width; }
double height() const { return _height; }
};
#endif
Box.cpp
#include "Box.h"
#include <iostream>
Box::Box(double length, double width, double height) : _length {length}, _width {width}, _height {height} {}
Box::Box(double side) : Box {side, side, side} {}
Box::Box(const Box& box) : Box {box.length, box.width, box.height} {}
// Function to calculate the volume of a box
double Box::volume() const {
return this -> _length * this -> _width * this -> _height;
}
main.cpp
#include <iostream>
#include <memory>
#include "Box.h"
int main() {
Box box1 {2.0, 3.0, 4.0};
Box box2;
auto box3 { std::make_unique<Box>(15.0, 20.0, 25.0) };
std::cout << "Volume of box1 = " << box1.volume() << std::endl;
std::cout << "Surface area of box1 = " << surfaceArea(box1) << std::endl;
std::cout << "Volume of box2 = " << box2.volume() << std::endl;
std::cout << "Surface area of box2 = " << surfaceArea(box2) << std::endl;
std::cout << "Volume of box3 = " << box3->volume() << std::endl;
std::cout << "Surface area of box3 = " << surfaceArea(*box3) << std::endl;
}
double surfaceArea(const Box& aBox) {
return 2.0 * (aBox._length * aBox._width + aBox._length * aBox._height + aBox._height * aBox._width);
}
Based on these error messages I'm concluding that there is an issue with the delegating constructor of the copy constructor. So i'm not sure why it seems like the code is calling the default constructor instead of the 3-arg constructor.
You have to add a pair of parenthesis if you want to call the functions:
Box::Box(const Box& box) : Box {box.length(), box.width(), box.height()} {}

How to make object of a class with parameterized constructor in other class?

I want to make an object of DataArea class in Area class and initialize data in main function. But the only way my code works is by initializing data in Area class.
Also, I do not know if I have made the object correctly or not. Please guide me. My code is below:
#include<iostream>
using namespace std;
class DataArea
{
public:
int radius, length, width, base, heigth;
DataArea(int l, int w, int b, int h, int r)
{
length = l;
width = w;
radius = r;
heigth = h;
base = b;
}
};
class Area
{
public:
DataArea* s = new DataArea(3, 4, 5, 6, 7);
float AreaCirle()
{
return 3.142 * s->radius * s->radius;
}
float AreaRectangle()
{
return s->length * s->width;
}
float AreaTraingle()
{
return (s->base * s->heigth) / 2;
}
};
class print_data : public Area
{
public:
void print()
{
cout << "Area of Circle is: " << AreaCirle() << endl;
cout << "Area of Rectangle is: " << AreaRectangle() << endl;
cout << "Area of Traingle is: " << AreaTraingle() << endl;
}
};
int main()
{
//DataArea da(3, 4, 5, 6, 7);
print_data m;
m.print();
}
Your DataArea is basically absolute if you do not use it outside of Area class. Similarly, print_data class can be replaced by an operator<< overload.
Following is the updated code, in which the comments will guide you through.
#include <iostream>
// DataArea (optionally) can be the part of Area class
struct DataArea /* final */
{
float length, width, base, height, radius;
DataArea(float l, float w, float b, float h, float r)
: length{ l } // use member initializer lists to initlize the members
, width{ w }
, base{ b }
, height{ h }
, radius{ r }
{}
};
class Area /* final */
{
DataArea mDataArea; // DataArea as member
public:
// provide a constructor which initialize the `DataArea` member
Area(float l, float w, float b, float h, float r)
: mDataArea{ l, w, b, h, r } // member initializer
{}
// camelCase naming for the functions and variables
// mark it as const as the function does not change the member
float areaCirle() const /* noexcept */
{
return 3.142f * mDataArea.radius * mDataArea.radius;
}
float areaRectangle() const /* noexcept */
{
return mDataArea.length * mDataArea.width;
}
float areaTraingle() const /* noexcept */
{
return (mDataArea.base * mDataArea.height) / 2.f;
}
// provide a operator<< for printing the results
friend std::ostream& operator<<(std::ostream& out, const Area& areaObject) /* noexcept */;
};
std::ostream& operator<<(std::ostream& out, const Area& areaObject) /* noexcept */
{
out << "Area of Circle is: " << areaObject.areaCirle() << "\n";
out << "Area of Rectangle is: " << areaObject.areaRectangle() << "\n";
out << "Area of Traingle is: " << areaObject.areaTraingle() << "\n";
return out;
}
int main()
{
// now construct the Area object like this
Area obj{ 3, 4, 5, 6, 7 };
// simply print the result which uses the operator<< overload of the Area class
std::cout << obj;
}
Output:
Area of Circle is: 153.958
Area of Rectangle is: 12
Area of Traingle is: 15
It seems to me that Area class is surplus for what you are trying to achieve. You should probably put methods directly in DataArea class. Then you can create as many of DataArea objects as you like...
Like this:
class DataArea
{
public:
int radius, length, width, base, heigth;
DataArea(int l , int w , int b , int h , int r )
{
length = l;
width = w;
radius = r;
heigth = h;
base = b;
}
float AreaCirle()
{
return 3.142 * radius * radius;
}
float AreaRectangle()
{
return length * width ;
}
float AreaTraingle()
{
return (base * heigth)/2;
}
};
int main(int argc, char **argv)
{
DataArea area1 (1,2,3,4,5);
DataArea area2 (8,2,3,4,5);
std::cout << area1.AreaCirle() << std::endl;
std::cout << area2.AreaCirle() << std::endl;
}
The reason why you are probably having trouble to understand the concept:
You're defining a class and instantiating an object. Sometimes these terms are used interchangeably, but in this case, this is an important distinction.
If you would like for your methods to operate on some other class, that you should make methods that accept that class as an argument. Otherwise, it is unnecessary complex.

Visual Studio 2015 Error C3867 'Rectangle::get_area': non-standard syntax; use '&' to create a pointer to member

I am having difficulty understanding why I get this error in the context of my simple program using a user defined class "Rectangle"
The Rectangle class I made is used to create rectangles by inputting length/width, then printing l/w/area.
I have looked in these locations so far in an attempt to understand the issue, and still can not understand the problem.
https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=EN-US&k=k(C3867)&rd=true
Visual Studio 2015 "non-standard syntax; use '&' to create a pointer to member"
Visual Studio 2015 "non-standard syntax; use '&' to create pointer for member"
(I do not understand what pointers are, I have not learned about them yet in the book Stroustrup: Programming -- Principles and Practice Using C++ 2nd Ed.# Ch.10)
Here is my Rectangle.h
#include "stdafx.h"
#include <iostream>
using namespace std;
class Rectangle {
public:
Rectangle();
Rectangle(double dblp_length, double dblp_width);
bool is_square() const;
void set_length(double dblp_length);
double get_length() const;
void set_width(double dblp_width);
double get_width() const;
void set_area(double dblp_length, double dblp_width);
double get_area() const;
void print(ostream & output);
private:
void Rectangle::init(double dblp_length, double dblp_width);
double dbl_length, dbl_width, dbl_area;
};
My Rectangle.cpp
#include "stdafx.h"
#include "Rectangle.h"
#include <iostream>
Rectangle::Rectangle() {
init(8, 8);
}
Rectangle::Rectangle(double dblp_length, double dblp_width) {
init(dblp_length, dblp_width);
}
void Rectangle::init(double dblp_length, double dblp_width) {
set_length(dblp_length);
set_width(dblp_width);
}
void Rectangle::set_length(double dblp_length) {
if (dblp_length < 0 || dblp_length > 1024) {
dblp_length = 8;
}
double dbl_length = dblp_length;
}
double Rectangle::get_length() const {
return dbl_length;
}
void Rectangle::set_width(double dblp_width) {
if (dblp_width < 0 || dblp_width > 1024) {
dblp_width = 8;
}
double dbl_width = dblp_width;
}
double Rectangle::get_width() const {
return dbl_width;
}
bool Rectangle::is_square() const {
if (get_length() == get_width()) {
return true;
}
}
void Rectangle::set_area(double dblp_length, double dblp_width) {
double dbl_area;
dbl_area = (dblp_length * dblp_width);
}
double Rectangle::get_area() const {
return dbl_area;
}
void Rectangle::print(ostream & output) {
output << "Length: " << get_length() << ", " <<
"Width :" << get_width() << ", " <<
"Area: " << get_area << endl;
}
Here is the corrected version, with reasons and original code commented.
Potential problem:
area has not set by init, and can be set to a value that get_area() != get_width() * get_length()
Rectangle.h
#include "stdafx.h"
#include <iostream>
using namespace std;
class Rectangle {
public:
Rectangle();
Rectangle(double dblp_length, double dblp_width);
bool is_square() const;
void set_length(double dblp_length);
double get_length() const;
void set_width(double dblp_width);
double get_width() const;
void set_area(double dblp_length, double dblp_width);
double get_area() const;
void print(ostream & output);
private:
// Remove "Rectangle::" from here
// This is not work for gcc and clang
// void Rectangle::init(double dblp_length, double dblp_width);
void init(double dblp_length, double dblp_width);
double dbl_length, dbl_width, dbl_area;
};
Rectangle.cpp:
#include "stdafx.h"
#include "Rectangle.h"
#include <iostream>
Rectangle::Rectangle() {
init(8, 8);
}
Rectangle::Rectangle(double dblp_length, double dblp_width) {
init(dblp_length, dblp_width);
}
void Rectangle::init(double dblp_length, double dblp_width) {
set_length(dblp_length);
set_width(dblp_width);
}
void Rectangle::set_length(double dblp_length) {
if (dblp_length < 0 || dblp_length > 1024) {
dblp_length = 8;
}
// "double" is not needed, it introduced a local variable instead of
// changing the instance variable.
// double dbl_length = dblp_length;
dbl_length = dblp_length;
}
double Rectangle::get_length() const {
return dbl_length;
}
void Rectangle::set_width(double dblp_width) {
if (dblp_width < 0 || dblp_width > 1024) {
dblp_width = 8;
}
// "double" is not needed, it introduced a local variable instead of
// changing the instance variable.
// double dbl_width = dblp_width;
dbl_width = dblp_width;
}
double Rectangle::get_width() const {
return dbl_width;
}
bool Rectangle::is_square() const {
// missing the false part
// if (get_length() == get_width()) {
// return true;
// }
// return the boolean value directly instead
return get_length() == get_width();
}
void Rectangle::set_area(double dblp_length, double dblp_width) {
// this line is not needed, it introduced a local variable,
// making future assignment assigns to local instead of instance variable
// double dbl_area;
dbl_area = (dblp_length * dblp_width);
}
double Rectangle::get_area() const {
return dbl_area;
}
void Rectangle::print(ostream & output) {
output << "Length: " << get_length() << ", " <<
"Width :" << get_width() << ", " <<
// missing () after get_area
// "Area: " << get_area << endl;
"Area: " << get_area() << endl;
}

Implementing operator<< for a derived class

So I have a base class (Shape) and three derived classes, Circle, Rectangle and Square (Square is derived from Rectangle) I'm attempting to implement operator<< which just calls the correct display function for what called it. However, I don't think I have the syntax correct. Here's a snippet--where have I gone wrong?
class Shape
{
public:
Shape(double w = 0, double h = 0, double r = 0)
{
width = w;
height = h;
radius = r;
}
virtual double area() = 0;
virtual void display() = 0;
protected:
double width;
double height;
double radius;
};
ostream & operator<<(ostream & out, const Shape & s)
{
s.display(out);
return out;
}
class Rectangle : public Shape
{
public:
Rectangle(double w, double h) : Shape(w, h)
{
}
virtual double area() { return width * height; }
virtual void display()
{
cout << "Width of rectangle: " << width << endl;
cout << "Height of rectangle: " << height << endl;
cout << "Area of rectangle: " << this->area() << endl;
}
};
You're calling display like this:
s.display( out );
But display is defined as:
vritual void display() = 0;
The function was declared and defined taking no parameters. It should take a reference to std::ostream as a parameter:
virtual void display(std::ostream &) = 0;
It should also be a const method as you're passing in a const object through the operator << overload:
virtual void display(std::ostream &) const = 0;
Don't forget that in the definition of display you should be writing to the ostream object, not specifically std::cout.
Here is a compiling program on Ideone.
You have a number of problems here. Firstly, let's deal with the printing problem:
ostream & operator<<(ostream & out, const Shape & s)
Here, you're passing a const Shape. This means you can only call const methods on the s you pass in. However, you haven't marked any of the methods in the base (or derived) class as const. Neither area nor display should change the state of the object. Secondly, you're trying to call s.display(out), that is, passing an ostream& to display. The function signature you have doesn't reflect this. So putting that all together we get:
virtual double area() const = 0;
virtual void display(ostream& out) const = 0;
You've also got some other problems - a base class that doesn't declare a virtual destructor. If you're planning on using a class polymorphically, it must have a virtual destructor:
virtual ~Shape() { }
You also need to amend your methods in the derived class:
double area() const { return width * height; }
void display(ostream& out) const
{
out << "Width of rectangle: " << width << endl;
out << "Height of rectangle: " << height << endl;
out << "Area of rectangle: " << area() << endl;
}
Note that display in Rectangle was always printing to cout beforehand.
You almost got it right, here is the working solution:
#include <iostream>
using std::cout;
using std::endl;
using std::ostream;
class Shape
{
public:
Shape(double w = 0, double h = 0, double r = 0)
{
width = w;
height = h;
radius = r;
}
virtual ~Shape() {} // Recommended!
virtual double area() const = 0;
virtual void display(ostream & out) const = 0;
protected:
double width;
double height;
double radius;
};
ostream & operator<<(ostream & out, const Shape & s)
{
// Since `s` is `const`, then `display` method should be `const` too.
s.display(out);
return out;
}
class Rectangle : public Shape
{
public:
Rectangle(double w, double h) : Shape(w, h)
{
}
virtual double area() const { return width * height; }
virtual void display(ostream & out) const
{
// Since `display` method is `const`, then `area` method should be
// `const` too.
out << "Width of rectangle: " << width << endl;
out << "Height of rectangle: " << height << endl;
out << "Area of rectangle: " << this->area() << endl;
}
};
void main() {
Rectangle r(1, 2);
cout << r << endl;
}
Please, pay attention to the const qualifiers which enforce const-correctness of class methods. I've added some useful comments so that you can follow the logic smoothly. Take it as a rule of thumb, if the method does not modify class members, then you should declare it const.