Getting method is undefined in C++ - c++

I'm trying to create a program from a C++ tutorial. But the IDE the tutor is using is VS2010 and I'm using VS2017. I noticed some of the syntaxes(sp.) are slightly different. I'm not sure what this error is and I've tried searching.
Here's the main .cpp:
#include "stdafx.h"
#include <iostream>
#include "Utility.h"
using namespace std;
int main()
{
int x;
cout << "Enter a Number: " << endl;
cin >> x;
if (IsPrime(x))
cout << x << " is prime" << endl;
else
cout << x << " is not prime" << endl;
if (Is2MorePrime(x))
cout << x << "+2 is prime" << endl;
else
cout << x << "+2 is not prime" << endl;
return 0;
}
The methods being tested out in the if conditions are both returning a "included method: identifier not found" and "included method: identifier is undefined"
Here's the included class .cpp:
#include "stdafx.h"
#include "Utility.h"
#include <iostream>
using namespace std;
bool Utility::IsPrime(int num)
{
bool prime = true;
for (int i = 0; i <= num / i; i++)
{
int factor = num / i;
if (factor*i == num)
{
cout << "Factor Found: " << factor << endl;
prime = false;
break;
}
}
return prime;
}
bool Utility::Is2MorePrime(int num)
{
num += 2;
return IsPrime(num);
}
And here's the included header file:
#pragma once
class Utility
{
bool IsPrime(int primeNum);
bool Is2MorePrime(int morePrime);
};
I'm still new to C++ programming so I don't know anything intensive yet.

The methods are in the Utility class yet you are calling them from main with no instance of Utility so the compiler/linker is looking for methods that don't exist.
You could probably make them static members of Utility and then you just need to scope the calls (e.g. Utility::IsPrime(x)) and not actually have an instance of Utility.
As mentioned by #Amadeus in the comments: If everything in Utility is "stateless" and can be static, then perhaps you should be putting all the Utility methods in a namespace instead of a class.

Related

GCD recursion function RTE in some IDEs

Trying to implement gcd int function using Euclidean Algorithm with recursion. Results from CodeBlocks differ from IDEone (which I use to test my code before submitting to a CP website, TLX: https://tlx.toki.id, which I assume has similar compilers etc. because a lot of times IDEone and TLX got RTE while in CodeBlocks it ran without any problem). First Question: 1. Do they actually have something different that affects the output?
My first attempt was as follows:
#include <iostream>
#include <cmath>
using namespace std;
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#define pass (void)0
#include <cstdio>
#include <cstring>
#define ll long long
int gcd(int x, int y){
if(y!=0){
gcd(y, x%y);
//return x%y;
} else {
return x;
}
}
int main() {
cout << "test" << endl;
int z = gcd(100, 10);
cout << z << " bruh" << endl;
cout << "hello" << endl;
}
which IDEone spits out
Runtime error #stdin #stdout 0.01s 5380KB
test
while it ran as expected (z = 1 and prints out the correct stuff) in CodeBlocks
I tried to pinpoint where the error exactly occurs by 1. printing out at what part of the code my computer went error by the following way
void gcd(int x, int y){
if(y!=0){
cout << "if " << x << ", " << y << endl;
gcd(y, x%y);
} else {
cout << "else " << x << ", " << y << endl;
//return x;
}
}
int main() {
cout << "test" << endl;
//int z = gcd(100, 10);
gcd(100, 10);
//cout << z << " bruh" << endl;
cout << "hello" << endl;
}
which in both IDE, it outputted:
test
if 100, 10
else 10, 0
hello
then I also tried:
int gcd(int x, int y){
if(y!=0){
gcd(y, x%y);
//return x%y;
} else {
return x;
}
}
int main() {
cout << "test" << endl;
int z = gcd(100, 10);
cout << z << " bruh" << endl;
cout << "hello" << endl;
}
CodeBlocks outputted the first, while IDEone had an error as in the second
test
10 bruh
hello
Runtime error #stdin #stdout 0.01s 5380KB
test
from what I've tried and understand so far, it seems there's an error when the function gcd() calls the gcd() function. 2. Is my assumption correct? 3. and how am I supposed to solve this problem?
Thanks in advance
The problem is that the recursive case of the gcd() function does not run a return statement. Thus, it should be modified like this:
int gcd(int x, int y){
if(y!=0){
return gcd(y, x%y);
} else {
return x;
}
}
This could easily have been caught by enabling and reading compiler warnings.

how can i use aggregation while separating my classes into a .h and .cpp files?

Context
My professor gave me a task to make a program using aggregation between 2 classes while also separating the classes into a .h and .cpp files.
My solution
The header file containing the class declaration:
#include <iostream>
#include <string>
using namespace std;
class medicalCompany {
private:
string ceoName;
string email;
string phoneNumber;
string locate;
public:
medicalCompany();
void Name(string n);
void mail(string m);
void phone(string p);
void location(string l);
~medicalCompany();
};
class origin {
private:
medicalCompany country;
public:
origin();
void address();
~origin();
};
and my .cpp file:
#include <iostream>
#include "function.h"
#include <string>
using namespace std;
medicalCompany::medicalCompany() {
cout << "OUR COMPANY IS GLAD TO BE OF SERVICE !" << endl;
cout << "****************************************************" << endl;
}
void medicalCompany::Name(string n){
ceoName = n;
cout << "OUR CEO IS " << endl;
cout<< ceoName << endl;
cout << "****************************************************" << endl;
}
void medicalCompany::mail(string m) {
email = m;
cout << "USE OUR EMAIL TO CONTACT US : " << endl;
cout<< email << endl;
cout << "****************************************************" << endl;
}
void medicalCompany::phone(string p) {
phoneNumber = p;
cout << "THIS IS OUR CUSTOMER SERVICE PHONE NUMBER " << endl;
cout<< phoneNumber << endl;
cout << "****************************************************" << endl;
}
void medicalCompany::location(string l) {
locate = l;
cout << " OUR COMPANY IS LOCATED IN " << endl;
cout << locate << endl;
cout << "****************************************************" << endl;
}
medicalCompany::~medicalCompany() {
cout << "thanks for trusting our company ^_^" << endl;
cout << "****************************************************" << endl;
}
origin::origin() {
cout<< "constructor 2"<<endl;
}
void origin::address() {
cout << country.location;
}
origin::~origin() {
cout << "bye" << endl;
}
The two classes are used in my main.cpp file:
#include <iostream>
#include <string>
#include "function.h"
using namespace std;
int main() {
medicalCompany o;
o.Name("jack");
o.mail("ouremail#company.com");
o.phone("2342352134");
o.location("Germany");
origin o2;
return 0;
}
Problem
I run into this error :
Severity Code Description Project File Line Suppression State
Error C3867 'medicalCompany::location': non-standard syntax; use '&' to create a pointer to member CP2_HW c:\function.cpp 41
You can either:
replace void origin::address(){cout << country.location;} by void origin::address(){country.location();}
or by void origin::address(){cout << country.locate;} if you put the locate member as a public variable.
Also, few remarks:
Generally you would prefer avoiding exposing private members, so the first solution should be prefered.
the instruction using namespace std; is usually considered bad practice, and should be avoided, as the cost of possible risks does not overweight the benefit of not having to type std::cout(see this question for more information)
In terms of naming convention, I would have exchanged the names of locate and location: location should be the member variable and locate the action (function) of getting the location.
Prefer using a constructor and intialization lists rather than getter/setter.
Your output formatting should be very separate from the logic of your classes, for example implementing a << operator for your class.
Following this logic, your code should look more like:
#include <iostream>
#include <string>
class medicalCompany {
private:
std::string _ceoName;
std::string _email;
std::string _phoneNumber;
std::string _location;
public:
// Constructor
medicalCompany(std::string name, std::string email, std::string phone, std::string location):
_ceoName(name),
_email(email),
_phoneNumber(phone),
_location(location)
{}
friend ostream& operator<<(ostream& os, const medicalCompany& dt);
};
and for the ostream operator:
ostream& operator<<(ostream& os, const medicalCompany& co)
{
os << co._ceoName << " " co._phoneNumber << ' ' << co._email;
return os;
}
This would allows to write code like this in your main:
int main() {
medicalCompany o("jack", "ouremail#company.com","2342352134","Germany")
std::cout << o << std::endl;
return 0;
}
The code is not functional and you would have to edit it to fit your formating requirement, but you have the idea :) Good luck!

vector<string> in a struct doesn't work properly

I declared a vector<string> and I cannot even compile it. I tried many ways but none of them worked.
I'm trying to write out the x.surname.push_back(word)[i] but it's definetly written wrongly and I have no idea how to write it properly and make it possible to compile.
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
int main() {
int number, i = 0;
string word;
struct donators {
vector<string> surname;
vector<int> amount;
} x;
cout << "How many donators do you want to register? " << endl;
cin >> number;
for (i = 0; i < number; i++) {
cout << "Surname: ";
cin >> word;
x.surname.push_back(word)[i];
cout << "Amount: ";
x.amount.push_back(i);
cin >> x.amount[i];
}
cout << "OUR GORGEUS DONATORS: " << endl;
for (i = 0; i < number; i++) {
if (x.amount[i] >= 10000) {
cout << "Surname: " << x.surname(word)[i];
cout << "Amount: " << x.amount[i] << endl;
}
else if (x.amount[i] < 10000) {
cout << "Lack of surnames!" << endl;
}
}
cout << "OUR CASUAL DONATORS: " << endl;
for (i = 0; i < number; i++) {
if (x.amount[i] < 10000) {
cout << "Surname: " << x.surname(word)[i];
cout << "Amount: " << x.amount[i] << endl;
} else if (x.amount[i] >= 10000) {
cout << "Lack of surnames!" << endl;
}
}
return 0;
}
And one more thing. How to make sentence "Lack of surnames!" to be written out once? In some cases, it is written out twice or more times what is redundant.
You are putting [i] at seemingly random places in your code. Such as in x.surname.push_back(word)[i];. Don't add things like this to your code if you're unsure about what they're doing.
The x.surname(word)[i] construct are also wrong. What's x.surname(word) supposed to be? This syntax is for function calls. surname, however, is not a function. It's a std::vector<std::string>. Just put x.surname[i] instead.
And one more thing. How to make sentence "Lack of surnames!" to be
written out once? In some cases, it is written out twice or more times
what is redundant.
That's because you write it for every donor that doesn't fit the criterion. Instead, keep track if any donor fits the criterion and only print it when none ends up fitting. You can do it like this:
bool HasGorgeousDonators = false;
And then in the loop:
if (x.amount[i] >= 10000)
{
cout << "Surname: " << x.surname[i];
cout << "Amount: " << x.amount[i] << endl;
HasGorgeousDonators = true;
}
And after the loop:
if (!HasGorgeousDonators)
cout << "Lack of surnames!" << endl;
Likewise for the other loop. Also, please consider the following Q&A:
Why is "using namespace std;" considered bad practice?
It seems like you are writing C with some C++ help functions. However C++ is a different language. Sure, it supports some C structures, but there's so much more.
Take a look at some of my suggestions for implementation and compare it to your code:
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
template<typename T>
T ReadCin(std::string_view const& sv = "") {
T retVal;
if (!sv.empty()) std::cout << sv;
std::cin >> retVal;
return retVal;
}
class Donator {
private:
std::string surname{};
int amount{};
public:
constexpr bool IsGenerous() const noexcept { return amount >= 10000; }
void Read() noexcept {
surname = ReadCin<decltype(surname)>("Surname: ");
amount = ReadCin<decltype(amount)>("Amount: ");
}
friend std::ostream& operator<<(std::ostream& out, Donator const& donator) noexcept {
out << "Surname: " << donator.surname << ", " << "Amount: " << donator.amount;
return out;
}
};
int main() {
std::vector<Donator> donators(ReadCin<int>("How many donators do you want to register?\n"));
for (auto& donator : donators) donator.Read();
std::cout << "OUR GENEROUS DONATORS:\n";
std::copy_if(std::cbegin(donators), std::cend(donators), std::ostream_iterator<Donator>(std::cout, "\n"),
[](Donator const& donator) { return donator.IsGenerous(); });
std::cout << "OUR CASUAL DONATORS:\n";
for (auto const& donator : donators) if (!donator.IsGenerous()) std::cout << donator << '\n'; //alternative
}
I tried to include some of the possibilities using C++. I would really advise you to get a good book on C++.

C++ Using array and for loop to output from multiple classes

I am asked to do this code and i need to use array or something similar to print out different classes. The only way i know is individually doing every single class is there a faster way of doing this. Following is the way i am using at the moment.
Ground_Transport Gobj;
Air_Transport Aobj;
Sea_Transport Sobj;
Car Cobj;
Train Tobj;
Bus Bobj;
Gobj.estimate_time();
Gobj.estimate_cost();
cout << Gobj.getName() << endl;
Bobj.estimate_time();
Bobj.estimate_cost();
cout << Bobj.getName() << endl;
Sobj.estimate_time();
Sobj.estimate_cost();
cout<<Sobj.getName()<<endl;
Aobj.estimate_time();
Aobj.estimate_cost();
cout << Aobj.getName() << endl;
Cobj.estimate_time();
Cobj.estimate_cost();
cout << Cobj.getName() << endl;
Tobj.estimate_time();
Tobj.estimate_cost();
cout << Tobj.getName() << endl;
Transport_KL_Penang Kobj;
cout << Kobj.getName() << endl;
This is the header file Transport_KL_Penang
#include <iostream>
#include <string>
using namespace std;
class Transport_KL_Penang
{
public:
Transport_KL_Penang() {}
virtual string getName() {
return Name;
}
int Time_in_hours1 ;
int Time_in_hours2 ;
int Cost_in_RM1 ;
int Cost_in_RM2 ;
void estimate_time() ;
void estimate_cost() ;
private:
static string Name;
};
void Transport_KL_Penang::estimate_time()
{
cout << "It takes " << Time_in_hours1 << "-" << Time_in_hours2 <<
" hours if you use " << Name << endl;
}
void Transport_KL_Penang::estimate_cost()
{
cout << "It will cost around " << Cost_in_RM1 << "-" << Cost_in_RM2 <<
"RM if you use " << Name << endl;
}
If you don't need a specific object name, you can write something as a code below, creating a multiples generics objects:
#include <iostream>
#include <cstdlib>
#include <time.h>
class Myclass {
private:
int randTime;
float cost;
public:
void estimate_time(){
randTime = rand()%100;
}
void estimate_cost(){
cost = randTime * 0.2;
}
float getEstimateCost(){
return cost;
}
};
int main(){
srand(time(NULL));
int numberOfObjects = 7;
Myclass obj[numberOfObjects];
//input
for(int i = 0; i < numberOfObjects; i++){
obj[i].estimate_time();
obj[i].estimate_cost();
}
// printing
for(int i = 0; i < numberOfObjects; i++){
std::cout << obj[i].getEstimateCost() << std::endl;
}
return 0;
}

C++ Recursive functions

I'm learning C++ and I have trouble with getting recursion working when a function is called by itself.
#include <iostream>
using namespace std;
int countdown(int y) {
if (y==1) {
return 1 && cout << y << endl;
}
else {
return countdown(y-1);
}
}
int main () {
cout << "Countdown from ten: " << endl;
cout << countdown(10) << endl;
}
Of course there are other ways to achieve this, but really I created this example to verify my own understanding of how functions are called recursively.
In the example I added && cout << y to verify if y is being passed to the function as 1, which always appears to be the case irrespective that I call the function as countdown(10).
Could someone tell me if I'm missing something obvious here please?
Your ' cout << y ' only executes if y has been tested to be one.
This version does what I think you want:
#include <iostream>
using namespace std;
int countdown(int y)
{
cout << y << endl;
if (y==1)
{
return 1;
}
else
{
return countdown(y-1);
}
}
int main()
{
cout << "Countdown from ten: " << endl;
cout << countdown(10) << endl;
}
Your call stack looks like this:
main
countdown(10)
countdown(9)
countdown(8)
countdown(7)
countdown(6)
countdown(5)
countdown(4)
countdown(3)
countdown(2)
countdown(1)
std::cout << 1 << std::endl;
If you want to see the whole countdown, move the output command in front of the if condition.
Also, your style of writing the output is very unidiomatic. Note that it only works because 1 %&& cout converts the cout to bool and bool can be converted to int. Please don't write code like that.