C2597 illegal reference to non static member - c++

Trying to get this homework figured out and I just keep hitting one wall after another. What I am getting now is the error message:
Error 1 error C2597: illegal reference to non-static member 'circleType::radius'
I have 2 header files, circleType.h and cylinderType.h and I need to out put results for shipping and painting costs that a user would enter. A little help before I go completely out of my mind ... Thank you.
circle.h
class circleType
{
public:
static void setRadius(double r);
double getRadius();
double area();
double circumference();
circleType(double r = 0);
private:
double radius;
};
void circleType::setRadius(double r)
{
if (r >= 0)
{
radius = r;
}
else
{
radius = 0;
}
}
double circleType::getRadius()
{
return radius;
}
double circleType::area()
{
return 3.1416 * radius * radius;
}
double circleType::circumference()
{
return 2 * 3.1416 * radius;
}
circleType::circleType(double r)
{
setRadius(r);
}
cylinderTyper.h
#include "circleType.h"
class cylinderType: public circleType
{
public:
static void setRadius(double r);
static double getRadius();
static double area();
static double circumference();
cylinderType(double r = 0);
private:
double radius;
};
main.cpp
#include "stdafx.h"
#include "cylinderType.h"
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
void enterData(int& cylinderBase,int& cylinerHeight, double& shipCost, double& paintCost);
int main()
{
cout << fixed << showpoint << setprecision(2);
int cylinderBase, cylinderHeight;
double sCost, pCost, shipCost, paintCost, volume, area = 0, circumference = 0;
enterData(cylinderBase, cylinderHeight, shipCost, paintCost);
cylinderType::setRadius(cylinderBase + cylinderHeight);
cylinderType::getRadius();
cylinderType::area();
cylinderType::circumference();
cout << "Cost of shipping: $" << circumference * shipCost << endl;
cout << "Cost of painting: $" << area * paintCost << endl;
system("pause");
return 0;
}
void enterData(int& cylinderBase, int& cylinderHeight, double& shipCost, double& paintCost)
{
cout << "Enter the base size of cylinder: ";
cin >> cylinderBase;
cout << endl;
cout << "Enter the hight size of cylinder: ";
cin >> cylinderHeight;
cout << endl;
cout << "Enter shipping cost per liter: ";
cin >> shipCost;
cout << endl;
cout << "Enter cost of painting per square foot: ";
cin >> paintCost;
cout << endl;
}

It's a very simple rule: static member functions can only access member variables that are static as well. That's because a static function isn't called against a specific object, so object members don't make sense in that context.
In your case, the static function setRadius is trying to modify the member variable radius which is not static. I suspect that you really don't want setRadius to be a static function.

Related

Displaying results of methods on the screen

My task is to practice inheritance, putting all the classes in separate files. I have a base class Circle and a derived class Cylinder.
What I'm stuck on is trying to display on the screen the result of my calculated area and volume for an object B of a Cylinder type. I found a way to do that for a Circle, though it doesn't work for my Cylinder.
circle.h
#pragma once
#include <iostream>
class Circle {
public:
float r;
Circle();
Circle(float r);
Circle circumference();
Circle area();
void view();
void getArea();
void getCircum();
};
circle.cpp
#include "circle.h"
#include <cmath>
using namespace std;
Circle::Circle() : r(5) {
cout << "Default constructor has been called for a circle\n";
}
Circle::Circle(float r) {
this->r = r;
cout << "Constructor with parameters has been called for a circle\n";
}
void Circle::view() {
cout << "Radius = " << r << endl;
}
Circle Circle::circumference() {
return 2 * M_PI * r;
}
Circle Circle::area() {
return M_PI * pow(r, 2);
}
void Circle::getArea() {
cout << "Area = " << r << " m^2";
}
void Circle::getCircum() {
cout << "Circumference = " << r << " m";
}
cylinder.h
#pragma once
#include <iostream>
#include "circle.h"
class Cylinder : public Circle {
public:
float h;
Cylinder();
Cylinder(float r, float h);
void view();
double area();
double volume(float r, float h);
void getArea();
void getVolume();
};
cylinder.cpp
#include "cylinder.h"
#include <cmath>
using namespace std;
Cylinder::Cylinder() : h(7) {
cout << "Default constructor has been called for a cylinder\n";
}
Cylinder::Cylinder(float r, float h) : Circle(r) {
this->h = h;
cout << "Constructor with parameters has been called fo a cylinder\n";
}
void Cylinder::view() {
Circle::view();
cout << "Height = " << h << endl;
}
double Cylinder::area() {
return 2 * M_PI * r * h;
}
double Cylinder::volume(float r, float h) {
return M_PI * pow(r, 2) * h;
}
void Cylinder::getArea() {
cout << "Area = " << h;
}
void Cylinder::getVolume() {
cout << "Volume = " << h;
}
main.cpp
#include <iostream>
#include "circle.h"
#include "cylinder.h"
using namespace std;
int main() {
Circle A;
A.view();
Circle A1(8);
A1.view();
Cylinder B;
B.view();
Cylinder B1(4, 6);
B1.view();
//A.area().getArea();
//cout << endl;
//A.circumference().getCircum();
//cout << endl;
//A1.area().getArea();
//cout << endl;
//A1.circumference().getCircum();
B.area().getArea();
return 0;
}
The error that I'm getting:
main.cpp: In function ‘int main()’:
main.cpp:26:14: error: request for member ‘getArea’ in ‘B.Cylinder::area()’, which is of non-class type ‘double’
26 | B.area().getArea();
| ^~~~~~~
I feel like neither my code in main() for instance B, nor my methods getArea() and getVolume() in class Cylinder, are correct. And there is probably a better approach to do the same for an object A and A1 of a Circle type, though the code I commented out actually works.
I know that this is a dumb question, and such things should be quite straightforward, but I am trying to learn and would be grateful for any advice on how I can fix this.
Well, the reason you are getting the error message:
main.cpp: In function ‘int main()’:
main.cpp:26:14: error: request for member ‘getArea’ in ‘B.Cylinder::area()’, which is of non-class type ‘double’
26 | B.area().getArea();
| ^~~~~~~
Is because you are basically doing this:
auto _ = B.area();
So here, _ deduces to be a double, and then you do:
_.getArea();
You are trying to access a member function from a double, and double doesn't have any member functions.
You probably meant to do this instead:
auto x = B.area();
B.h = x;
B.GetArea();
This assigns the area of B.area() to a variable x, and assigns x to B.h. B's member function then gets called and outputs the area.
In your getArea() function, instead of saying:
cout << "Area = " << endl;
Just say:
cout << "Area = " << area() << endl;
Then in your main.cpp, just call B.getArea().
Hope this helps!

error: expected a ';', bug in Intellisense when building?

I got an error in Visual Studio 2019, when building and using IntelliSense at the same time, which said that it expected a ';' (CODE: E0065 and the error is supposed to be on line 9), I am extremely confused because this is my first time getting an error like this when defining functions because it is also my first time defining functions in c++, I really don't know where I could be missing a semi colon. The program doesn't run.
#include <iostream>
using namespace std;
int main() {
const double pi{3.14159};
double calc_area_circle(double radius) {
return pi * (radius * radius);
}
void area_circle() {
double radius{};
cout << "Enter the radius of the circle: ";
cin >> radius;
cout << "The area of the circle with radius " << radius << " is " << calc_area_circle(radius) << endl;
}
return 0;
}
If any one could clear this up for me, I would really appreciate it.
Nesting of function definition (defining functions inside another functions) is not allowed in C++ unless you use lambda functions.
Put the function definitions outside the function
#include <iostream>
using namespace std;
const double pi{3.14159};
double calc_area_circle(double radius) {
return pi * (radius * radius);
}
void area_circle() {
double radius{};
cout << "Enter the radius of the circle: ";
cin >> radius;
cout << "The area of the circle with radius " << radius << " is " << calc_area_circle(radius) << endl;
}
int main() {
return 0;
}
or convert them to lambda function
#include <iostream>
using namespace std;
int main() {
const double pi{3.14159};
const auto calc_area_circle = [&](double radius) -> double {
return pi * (radius * radius);
};
const auto area_circle = [&]() {
double radius{};
cout << "Enter the radius of the circle: ";
cin >> radius;
cout << "The area of the circle with radius " << radius << " is " << calc_area_circle(radius) << endl;
};
return 0;
}
Note: these programs will do nothing because the defined functions are not called.

Cannot instantiate abstract class, but double checked overriding of virtual functions

I'm doing self-study C++. I tried a program from the book, that would normally allocate a few objects of two derived classes dynamically using an array of pointers. I'm however preparing for an assignment where I'm not allowed to use pointers, so I made an alternative version without pointers.
The only error it gives me is C2259 "cannot instantiate abstract class", but I'm pretty sure I have overriden all the virtual functions.
Here is the header:
#ifndef ACCTBAC_H_
#define ACCTBAC_H_
#include <iostream>
#include <string>
// Abstract Base Class
class AcctABC
{
private:
std::string fullName;
long acctNum;
double balance;
protected:
struct Formatting
{
std::ios_base::fmtflags flag;
std::streamsize pr;
};
const std::string& FullName() const { return fullName; }
long AcctNum() const { return acctNum; }
Formatting SetFormat() const;
void Restore(Formatting& f) const;
public:
AcctABC(const std::string& s = "Nullbody", long an = -1, double bal = 0.0);
void Deposit(double amt);
virtual void Withdraw(double amt) = 0; // pure virtual function
double Balance() const { return balance; };
virtual void ViewAcct() const = 0; // pure virtual function
virtual ~AcctABC() {}
};
// Brass Account Class
class Brass : public AcctABC
{
public:
Brass(const std::string& s = "Nullbody", long an = -1, double bal = 0.0) : AcctABC(s, an, bal) {}
virtual void Withdraw(double amt);
virtual void ViewAcct() const;
virtual ~Brass() {}
};
// Brass Plus Account Class
class BrassPlus : public AcctABC
{
private:
double maxLoan;
double rate;
double owesBank;
public:
BrassPlus(const std::string& s = "Nullbody", long an = -1, double bal = 0.0, double ml = 500, double r = 0.10);
BrassPlus(const Brass& ba, double ml = 500, double r = 0.1);
virtual void ViewAcct() const;
virtual void Withdraw(double amt);
void ResetMax(double m) { maxLoan = m; }
void ResetRate(double r) { rate = r; }
void ResetOwes() { owesBank = 0; }
};
#endif
the class functions:
// acctabc.cpp -- bank account class methods
#include <iostream>
#include "acctabc.h"
using std::cout;
using std::ios_base;
using std::string;
// Abstract Base Class
AcctABC::AcctABC(const string& s, long an, double bal)
{
fullName = s;
acctNum = an;
balance = bal;
}
void AcctABC::Deposit(double amt)
{
if (amt < 0)
cout << "Negative deposit not allowed; "
<< "deposit is cancelled.\n";
else
balance += amt;
}
void AcctABC::Withdraw(double amt)
{
balance -= amt;
}
// protected methods for formatting
AcctABC::Formatting AcctABC::SetFormat() const
{
// set up ###.## format
Formatting f;
f.flag = cout.setf(ios_base::fixed, ios_base::floatfield);
f.pr = cout.precision(2);
return f;
}
void AcctABC::Restore(Formatting& f) const
{
cout.setf(f.flag, ios_base::floatfield);
cout.precision(f.pr);
}
// Brass methods
void Brass::Withdraw(double amt)
{
if (amt < 0)
cout << "Withdrawal amount must be positive; "
<< "withdrawal cancelled.\n";
else if (amt <= Balance())
AcctABC::Withdraw(amt);
else
cout << "Withdrawal amount of $" << amt
<< " exceeds your balance.\n"
<< "Withdrawal cancelled.\n";
}
void Brass::ViewAcct() const
{
Formatting f = SetFormat();
cout << "Brass Client: " << FullName() << "\n";
cout << "Account Number: " << AcctNum() << "\n";
cout << "Balance: $" << Balance() << "\n";
Restore(f);
}
// BrassPlus methods
BrassPlus::BrassPlus(const string& s, long an, double bal, double ml, double r) : AcctABC(s, an, bal)
{
maxLoan = ml;
owesBank = 0.0;
rate = r;
}
void BrassPlus::ViewAcct() const
{
Formatting f = SetFormat();
cout << "BrassPlus Client: " << FullName() << "\n";
cout << "Account Number: " << AcctNum() << "\n";
cout << "Balance: $" << Balance() << "\n";
cout << "Maximum loan: $" << maxLoan << "\n";
cout << "Owed to bank: $" << owesBank << "\n";
cout.precision(3);
cout << "Loan Rate: " << 100 * rate << "%\n";
Restore(f);
}
void BrassPlus::Withdraw(double amt)
{
Formatting f = SetFormat();
double bal = Balance();
if (amt <= bal)
AcctABC::Withdraw(amt);
else if (amt <= bal + maxLoan - owesBank)
{
double advance = amt - bal;
owesBank += advance * (1.0 + rate);
cout << "Bank Advance: $" << advance << "\n";
cout << "Finance charge: $" << advance * rate << "\n";
Deposit(advance);
AcctABC::Withdraw(amt);
}
else
cout << "Credit limit exceeded. Transaction cancelled.\n";
Restore(f);
}
and the main program:
// usebrass3.cpp -- polymorphic example using an abstract base class
#include <iostream>
#include <string>
#include "acctabc.h"
#include <vector>
const int CLIENTS = 4;
int main()
{
using std::cin;
using std::cout;
using std::vector;
using std::string;
vector<AcctABC> accounts(CLIENTS);
string temp;
long tempnum;
double tempbal;
char kind;
for (int i = 0; i < CLIENTS; i++)
{
cout << "Enter client's name: ";
getline(cin, temp);
cout << "Enter client's account number: ";
cin >> tempnum;
cout << "Enter opening balance: $";
cin >> tempbal;
cout << "Enter 1 for Brass Account: ";
while (cin >> kind && (kind != '1' && kind != '2'))
cout << "Enter either 1 or 2: ";
if (kind == 1)
accounts.push_back(Brass(temp, tempnum, tempbal));
else
{
double tmax, trate;
cout << "Enter the overdraft limit: $";
cin >> tmax;
cout << "Enter the interest rate "
<< "as a decimal fraction: ";
cin >> trate;
accounts.push_back(BrassPlus(temp, tempnum, tempbal, tmax, trate));
}
while (cin.get() != '\n')
continue;
}
cout << "\n";
for (int i = 0; i < CLIENTS; i++)
{
accounts[i].ViewAcct();
cout << "\n";
}
cout << "Done.\n";
return 0;
}
Here:
vector<AcctABC> accounts(CLIENTS);
you are trying to create a vector of AcctABC with CLIENTS default constructed AcctABC elements. But you cannot have AcctABC elements when the class is abstract. You also cannot have Brass elements in a vector of AcctABCs. You need pointers when you want to store a polymorphic type in a vector.
You cannot do this
vector<AcctABC> accounts(CLIENTS);
because it will make CLIENTS number of default constructed abstract base classes. You will also lose polymorphism and induce object slicing. Instead
vector<std::unique_ptr<AcctABC>> accounts;
then for example
accounts.push_back(std::make_unique<Brass>(temp, tempnum, tempbal));

Pointers, dynamic variables, C++

Errors
I keep receiving errors when running this program. What do these errors mean? A screenshot is attached.
This is the problem:
A class Area that has two private variable members; units of type string and area_value of type float.
1) Input from the keyboard the area_value and its units. Compute one-half and one-quarter of the area and display the results with unit.
2) Destroy the dynamic variable at the end.
#include <iostream
#include <string>
using namespace std;
class Area
{
public:
Area();
void setu(string a);
void seta(float b);
string getu();
float geta();
private:
string unit;
float area_value;
};
int main()
{
Area *p = new Area();
string a;
float f;
cout << "Enter a unit with no space: ";
getline(cin, a);
p->setu(a);
cout << "Enter a value of area: ";
cin >> f;
p->seta(f);
cout << "A half of your input = " << f / 2 << endl;
cout << "A quarter of your input = " << f / 4 << endl;
delete p;
return 0;
}
Looks like
You have not implemented the member functions, or
You have implemented the member functions in a separate file and forgot to include it in building the executable.
It seems you forgot to implement the constructor Area() and the methods of your Area class.
The first include is missing greater than sign (>). The public Area class only defines the functions, not implementing them. Variable p is defined as a pointer.
You can also add half and quarter as functions. I modified it slightly so it compiles with clang++ -Wall -std=c++11 -o area area.cpp.
#include <iostream>
#include <string>
using namespace std;
class Area {
public:
Area() {};
~Area() {};
void setu(string u) { unit = u; }
void seta(float a) { area_value = a; }
string getu() { return unit; }
float geta() { return area_value; }
float getHalf() { return area_value / 2; }
float getQuarter() { return area_value / 4; }
private:
string unit;
float area_value;
};
int main() {
Area p {};
string a;
float f;
cout << "Enter a unit with no space: ";
getline(cin, a);
p.setu(a);
cout << "Enter a value of area: ";
cin >> f;
p.seta(f);
cout << "A half of your input = " << p.getHalf() << endl;
cout << "A quarter of your input = " << p.getQuarter() << endl;
return 0;
}

C++ "undefined reference to class::function" [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 9 years ago.
So far I've managed to fix my own errors, but this one is keeping me puzzled for a while now. If any of you have any hints, that would be greately appreciated! Thanks.
I'm using Eclipse on a Windows laptop, which gives me the following error after building:
undefined reference to `Point::Point()' circle.cpp
/Assignment4_1/IN4084MSc line 13 C/C++ Problem
All my files (main4_1.cpp, point.h, point.cpp, circle.h, circle.cpp) are part of a project (called Assignment4_1).
#include "point.h"
#include "circle.h"
#include <cmath>
using namespace std;
Circle::Circle(Point ct, double rd):Point(ct)
{
center = ct;
if(rd > 0)
{
radius = rd;
}
radius = -1;
}
Point Circle::get_center(){
return center;
}
double Circle::get_radius(){
return radius;
}
void Circle::print(){
cout << " <Circle(<Point(“"<<center.get_x()<<"”,“"<<center.get_y()<<"”)>,”"<<radius<<"”)>";
}
void Circle::print(string s){
cout << s;
print();
}
void Circle::println(){
print();
cout << endl;
}
void Circle::println(string s){
print(s);
cout << endl;
}
#ifndef CIRCLE_H_
#define CIRCLE_H_
#include <iostream>
#include "point.h"
using namespace std;
class Circle: public Point{
Point center;
double radius;
public:
Circle(Point ct, double rd);
Point get_center();
double get_radius();
void print();
void print(string s);
void println();
void println(string s);
};
#endif /* CIRCLE_H_ */
#include "point.h"
#include <cmath>
using namespace std;
Point::Point(double x, double y){
x_coord = x;
y_coord = y;
}
double Point::get_x(){
return x_coord;
}
double Point::get_y(){
return y_coord;
}
void Point::print(){
//post: has printed the contents of the Point object in the format
cout << "<Point( “ " << x_coord <<" ” , “ " << y_coord << " ” )>";
}
void Point::print(string s){
//post: has printed string s first, then printed the contents of the Point object
cout << s << " ";
print();
}
void Point::println(){
//post: has printed the contents of Point object, then moved the cursor to the next line
print();
cout << endl;
}
void Point::println(string s){
//post: has printed string s first, then printed the contents of the Point object, and moved the cursor to the next line
cout << s << " ";
println();
}
void Point::move(double dx, double dy){
// post: x_coord = x_coord + dx, y_coord = y_coord + dy
x_coord = x_coord + dx;
y_coord = y_coord + dy;
}
double Point::distance(Point that){
//post: returns the distance between this Point and that Point
return sqrt( pow(x_coord - that.get_x(),2) + pow(y_coord - that.get_y(),2) );
}
bool Point::equals(Point that){
//post : returns true if this Point and that Point have the same coordinates
return (x_coord = that.get_x());
}
#ifndef POINT_H_
#define POINT_H_
#include <iostream>
using namespace std;
class Point{
protected:
double x_coord;
double y_coord;
public:
Point(double x, double y);
Point();
double get_x();
double get_y();
void print();
void print(string s);
void println();
void println(string s);
void move(double dx, double dy);
double distance(Point that);
bool equals(Point that);
};
#endif /* POINT_H_ */
#include <iostream>
#include <cstdlib>
using namespace std;
#include "point.h"
#include "circle.h"
void test1(){
cout << "test1:" << endl;
Point p1 = Point(2,3);
cout << "Point p1 is created, the data of p1 = (2,3)" << endl;
cout << "p1.get_x() -> " << p1.get_x() << endl;
cout << "p1.get_y() -> " << p1.get_y() << endl << endl;
p1.println("p1.println() -> ");
cout << endl;
cout << "end test1" << endl << endl;
}
void test2(){
cout << "test2:" << endl;
cout << "Point p1 is created, the data of p1 = (2,3)" << endl;
cout << "Point p2 is created, the data of p2 = (0,0)" << endl;
Point p1 = Point(2,3);p1.println("p1.println() -> ");
Point p2 = Point(0,0);p2.println("p2.println() -> ");
cout << endl;
p1.println("p1 before move -> ");
cout << "p1.move(1,1)" << endl;p1.move(1,1);
p1.println("p1 after move -> ");
cout << endl;
cout << "p1.distance(p2) -> " << p1.distance(p2) << endl << endl;
cout << "p1.equals(p1) -> " << p1.equals(p1) << endl;
cout << "p1.equals(p2) -> " << p1.equals(p2) << endl;
cout << "end test2" << endl << endl;
}
int main(){
test1();
test2();
return 0;
}
The compiler is telling you to define
Point::Point()
which you have only declared in the Point class definition. A possible implementation would be to initialize both coordinates with 0.0:
Point::Point() : x_coord(0.0), y_coord(0.0) {}
You have to explicitly initialize the members in this case because built-in types do not get zero-initialized when default constructed.