Question about implementing abstract functions in C++? - c++

I am learning and testing a piece of C++ code as follows:
#include "stdafx.h"
#include <iostream>
using namespace std;
#include <conio.h>
#include <cstring>
class Shape {
public:
Shape() {};
~Shape() {};
virtual void display() const = 0;
virtual double volume() const = 0;
};
class Square : public Shape {
public:
Square() {};
~Square() {};
void display() const;
double volume() const;
};
void Square::display() const {
cout << "Square!!!!!!!!!!!!!!" << endl;
}
double Square::volume() const {
cout << "Square Volume........." << endl;
return 0.0;
}
int _tmain(int argc, _TCHAR* argv[])
{
Shape *s;
s = new Square; // error here
(*s).display();
return 0;
}
The above code does not compile successfully. it produces: "fatal error LNK1120: 1 unresolved externals".
Can anyone help me out with that?
I am using MS VS C++ 2005.
Thanks

The above code compiles and runs properly on VS 2010 as well as Ideone.
Check this
There is nothing wrong in the way you have implemented your abstract functions in the above snippet.

I'm pretty sure your problem is your main declaration.
If you change it to a standard main definition, I believe your linking problems will be fixed.
int main()
{
Shape *s = new Square(); // error here
s->display();
return 0;
}

Related

Trying to access variables from another class

Im having an issue getting my variable from my original class to print in another class method
Quick example of my issue:
say the variable was declared here in the test.h file:
class player{
private:
int x = 10;
void setX(); //method for setting X from user input
int getX(); //Method for retrieving variable
}
Then in another class method where i want to print X
class inTheWoods{
public:
printInfo();
}
test.cpp file:
void player::setX(){
cout << "Set X to a number:" << endl;
cin >> x
}
int player::getX(){
return x;
}
int inTheWoods::printInfo(){
player playerObj; //Player object to access methods in player class
cout << playerObj.getX();
}
main.cpp:
int main(){
inTheWoods woodsObj;
woodsObj.printInfo();
return 0;
}
Whenever I run my program that resembles this problem the int does not display correctly and throws me a strange negative number. I hope this isnt too much code and that I documented everything correctly
If you want the classes to be in a separate files, it should still work:
Main.cpp
#include <iostream>
#include "inTheWoods.h"
int main()
{
inTheWoods woodsObj;
woodsObj.printInfo();
return 0;
}
Player.h
#pragma once
#include <iostream>
class Player
{
int x = 10;
void setX();
public:
int getX();
};
Player.cpp
#include "Player.h"
void Player::setX()
{
std::cout << "Set X to a number:" << std::endl;
std::cin >> x;
}
int Player::getX()
{
return x;
}
inTheWoods.h
//#pragma once
#include "Player.h"
#include <iostream>
class inTheWoods
{
public:
void printInfo();
};
inTheWoods.cpp
#include "inTheWoods.h"
void inTheWoods::printInfo()
{
Player playerObj; //Player object to access methods in player class
std::cout << playerObj.getX();
}
#pragma once is a preprocessor that prevents multiple includes, in case you didn't know. You can choose to skip it (Visual Studio auto-generated the file with the line).
In summary, these are the changes I needed to make from your implementation:
Move declaration of getX() from private to public.
Add semicolons to the end of every class.
Add a return type to printInfo(). If you don't want a function to return anything, the return type is void. Unless you care declaring a constructor, which doesn't seem to be the case here.
Here is the working one. It's always a good practice to give a constructor, in order to create an instance with some default values. the following code will work hopefully according to your requirements:
main.cpp
#include <iostream>
#include "inTheWoods.h"
int main()
{
inTheWoods woodsObj;
woodsObj.printInfo();
return 0;
}
player.h
#pragma once
class player
{
private:
int m_x;
public:
player();
player(const int& x);
void setX(); //method for setting X from user input
const int& getX()const; //Method for retrieving variable
};
player.cpp
#include "player.h"
#include <iostream>
player::player() // defualt constructor
:m_x(0) {}
player::player(const int& x)
:m_x(x) {} // parameterised
void player::setX()
{
std::cout << "Set X to a number:" << std::endl;
std::cin >> m_x;
}
const int& player::getX()const
{
return m_x;
}
inTheWoods.h
#pragma once
class inTheWoods
{
public:
inTheWoods();
~inTheWoods();
void printInfo();
};
inTheWoods.cpp
#include "inTheWoods.h"
#include "player.h"
#include <iostream>
inTheWoods::inTheWoods() {}
inTheWoods::~inTheWoods() {}
void inTheWoods::printInfo()
{
//Player object to access methods in player class
player playerObj; // will beinitialized with 0
player playerObj2(10); // will beinitialized with 10
std::cout << playerObj.getX() <<std::endl;
std::cout << playerObj2.getX() <<std::endl;
}
Edit: Well if you wanna allow the user to set values your printInfo() must be as follows:
void inTheWoods::printInfo()
{
//Player object to access methods in player class
player playerObj; // will beinitialized with 0
playerObj.setX();
std::cout << playerObj.getX() <<std::endl;
}

error C2509: member function not declared in derived class [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have base class State and derived class InitialState.When i build solution compiler show error C2509: 'setView': member function not declared in 'InitialState' and I don't know why...
Here is State.h :
#ifndef STATE_H
#define STATE_H
#include<iostream>
using namespace std;
class State {
public:
State() { isPrototype = true; }
virtual void execute() = 0;
virtual void setView(ostream& screen) const = 0;
virtual void onEnter() { system("CLS"); setView(cout); }
virtual void onExit() = 0;
private:
bool isPrototype;
State* nextState;
};
#endif
InitialState.h :
#ifndef INITIAL_STATE_H
#define INITIAL_STATE_H
#include"State.h"
class InitialState : public State {
public:
void execute() {}
void onExit() {}
void setView(ostream& screen) const;
};
#endif
and InitialState.cpp:
#include"InitialState.h"
void InitialState::setView(ostream& screen) const {
screen << "Welcome!" << endl;
screen << "Please select what you want to do: " << endl << "1.Load card" << endl << "0.Exit" << endl;
}
I have tried to add key word "virtual" in the front of functions in InitialState.h , but it doesn't change anything...also when I delete InitialState.cpp the code compiles normaly.
Here is the AtmTest.cpp:
#include "PaymentCard.h"
//#include "Atm.h"
int main() {
return 0;
}
but it has nothing with State...
and here are the other classes:
Atm.h:
#ifndef ATM_H
#define ATM_H
#include<iostream>
using namespace std;
class Atm {
public:
static Atm* get();
static void release() { delete instance; instance = nullptr; } //Singleton
private:
int serialNumber;
string bankName;
string location;
//Singleton:
Atm();
static Atm* instance;
Atm(const Atm& m) = delete;
Atm& operator=(const Atm& m) = delete;
Atm(Atm&&) = delete;
Atm& operator=(Atm&& m) = delete;
};
#endif
Atm.cpp:
#include"Atm.h"
//Singleton:
Atm* Atm::instance = nullptr;
Atm* Atm::get() {
if (instance == nullptr) {
instance = new Atm();
}
return instance;
}
PaymentCard.h:
#ifndef PAYMENT_CARD_H
#define PAYMENT_CARD_H
#include<iostream>
using namespace std;
class PaymentCard {
public:
PaymentCard(string clientName);
void addMoney(unsigned int amount) { currentAmount += amount; }
void withdrawMoney(int amount);
friend ostream& operator<< (ostream&, const PaymentCard&);
private:
static int NumberGenerator;
unsigned int serialNumber;
string clientName;
int currentAmount;
};
#endif
PaymentCard.cpp:
#include"PaymentCard.h"
int PaymentCard::NumberGenerator = 0;
PaymentCard::PaymentCard(string clientName) {
currentAmount = 0;
this->clientName = clientName;
serialNumber = NumberGenerator++;
}
void PaymentCard::withdrawMoney(int amount) {
if (amount > currentAmount)cout << "Ovde ide izuzetak";
else currentAmount -= amount;
}
ostream& operator<< (ostream &os, const PaymentCard& card){
os << card.serialNumber + 1 << ". Client: " << card.clientName << endl;
return os;
}
This code is not near the finish, but it worked until i have made SetView in InitialState, so idk what happened..
The problem: InitialState.h is precompiled, and you are linking to a prior version of InitialState.h. Clean, rebuild, and/or disable precompiled headers altogether.
I suspect that, because:
I can reproduce the error by commenting out the declaration of setView() in InitialState.h
The resulting error message refers to line 3 of InitialState.cpp and the error message you posted refers to line 6, which indicates that the posted source code did not produce that error message.
To reproduce the error, one has to comment out the setView() decalration from the InitialState class:
class InitialState : public State {
public:
void execute() {}
void onExit() {}
//void setView(ostream& screen) const;
};
Then one gets the following error message:
1>InitialState.cpp(3): error C2509: 'setView' : member function not declared in 'InitialState'
1> c:\users\laci\desktop\samples\stackoverflow\InitialState.h(6) : see declaration of 'InitialState'

Pointer to a different instance.

How can such a code work correctly when the IWindow pointer clearly has an address to a ISheet class which has no method Say?
#include <iostream>
using namespace std;
class IWindow
{
private:
int p;
double f;
public:
void Say() { cout << "Say in IWindow"; }
};
class ISheet
{
public:
void foo() { cout << "ISheet::foo"; }
};
int main()
{
ISheet *sh = new ISheet();
int ptr = (int)sh;
IWindow *w = (IWindow*)ptr;
w->Say();
sh->foo();
return 0;
}
When compiled in Visual Studio 2015 it runs and executes with no problems, but I was expecting to get an error on line w->Say(). How is this possible?
It works by the grace of the almighty Undefined Behavior. Your functions don't try to access any data members of the containing class, they just write something to std::cout, which anyone can do.
What you've effectively done is
#include <iostream>
void IWindow_Say(void*)
{
std::cout << "Say in IWindow";
}
int main()
{
IWindow_Say(0xdeadbeef); // good luck with that pointer
}
You never used the pointer (which became this in your original example) so no side-effects were observed.

c++ getter not returning changed value outside class

I have 1 main class
class Vehicle{
private:
int fuel;
public:
int get_fuel(){ return this->fuel; }
void set_fuel(int fuel){ this->fuel = fuel; }
};
also 1 subclass of Vehicle
class Car : public Vehicle{
public:
Car();
};
Car::Car(){
set_fuel(500);
}
also my main.cpp file
#include <cstdlib>
#include <iostream>
#include "Vehicle.h"
#include "Car.h"
using namespace std;
int main(int argc, char *argcv[]){
Car c;
cout << c.get_fuel() << endl; //500
//set fuel to 200
c.set_fuel(200);
//print fuel again
cout << c.get_fuel() << endl;//still 500
}
why after using the setter the value still remains the same after i use the getter?
On VC++ 2012 your exact code works as expected. Output is 500 and 200.
class Vehicle {
private:
int _fuel;
public:
Vehicle(){
_fuel = 0;
}
int get_fuel(){
return _fuel;
}
// I like chainable setters, unless they need to signal errors :)
Vehicle& set_fuel(int fuel){
_fuel = fuel;
return *this;
}
};
class Car : public Vehicle {
public:
Car():Vehicle(){
set_fuel(500);
}
};
// using the code, in your main()
Car car;
std::cout << car.get_fuel() << std::endl; // 500
car.set_fuel(200);
std::cout << car.get_fuel() << std::endl; // actually 200
This is a slightly modified version. Place it in your .CPP file and try it. It can't not work!
PS: Stop using properties that have the same name as arguments. Always having to use this-> is very not cool! When you'll forget to use the this->, you'll see the bug of the century when you'll assign the value to itself and can't figure out what goes wrong.

Getting an undefined reference error

I am hoping someone can point me in the right direction to figure out why I am getting the following error:
$~/display/triangleDisplayable.cc:4: undefined reference to `Displayable::Displayable()'
I am trying to abstract a class Displayable and have a class triangleDisplayable that implements its methods. The two header files I have are "Displayable.h":
class Displayable {
public:
Displayable();
virtual int getSizeOfArrays() = 0;
void display(int size);
private:
virtual void init() = 0;
virtual int getSizeOfPointsArray() = 0;
virtual int getSizeOfNormalsArray() = 0;
};
and "triangleDisplayable.h"
#include "Displayable.h"
class triangleDisplayable : public Displayable
{
public:
triangleDisplayable();
int getSizeOfArrays();
private:
void init();
int getSizeOfPointsArray();
int getSizeOfNormalsArray();
};
And then I have "Displayable.cc"
#include <iostream>
#include "Displayable.h"
Displayable::Displayable() {
std::cout << "testing Displayable constructor" << std::endl;
}
void Displayable:display(int size) {
}
int main () {
return 0;
}
and "triangleDisplayable.cc"
#include <iostream>
#include "triangleDisplayable.h"
triangleDisplayable::triangleDisplayable() : Displayable() {
}
int triangleDisplayable::getSizeOfArrays() {
return 0;
}
void triangleDisplayable::init() {
}
int triangleDisplayable::getSizeOfPointsArray() {
return 0;
}
int triangleDisplayable::getSizeOfNormalsArray() {
return 0;
}
int main () {
return 0;
}
I have been trying to follow along with various tutorials to learn how to do abstraction in C++, but I have not really been able to find any helpful solutions to this. I believe that all of my #includes are correct, which I read is a common problem. The error message seems to indicate that the problem is the line
triangleDisplayable::triangleDisplayable() : Displayable() {
}
I have tried to compile without the : Displayable() but I get the same error. Is there perhaps a problem with my syntax in my header files?
No, the error is in tool invocation. You need to link the two source files together (e.g. g++ -o foo a.cc b.cc). And remove one of the main functions, as you can't have two different ones.