I was given sample code in a C++ course I am taking. I can get it to build in CodeBlocks but not in Visual Studio 2015. In Visual Studio the main line "rename test3;" raises an error looking for a semicolon and the variable declaration in that line, "rename", is not highlighted in the default green for a type as it should be. Same for the next line. Therefore test3 and test4 come up as undefined. If I remove "#include <iostream>" "rename" turns to green in lines 33 and 34 but then the std include become undefined. Implementing "using namespace std" doesn't help either. I am attempting to get rid of "using namespace std" as it is not good coding practice from what I understand around here. I am missing a VS setting I think.
//#include <iostream> // original first two line
//using namespace std; //
#include <iostream>
#include <cstring> // I added this include
using std::cin; // I added the following using lines
using std::cout;
using std::endl;
class feature { // this class has a specific feature
private:
char data[16];
public:
feature() { strcpy(data, "default"); }
feature(char * in) { strcpy(data, in); } // error checks needed
void set(char * in) { strcpy(data, in); }
void out() { cout << data << endl; }
};
class rename : private feature {
public:
void reset(char * in) { set(in); }
void print() { out(); }
rename() : feature() {}
rename(char * in) : feature(in) {}
};
int main() {
feature test1;
feature test2("test2 data");
rename test3;
rename test4("test4 data");
test1.out();
test2.out();
test3.print();
test4.print();
}
The results should be:
default
test2 data
default
test4 data
default
test4 data
If I change back to the original first two lines the code does not work. If I rename "rename" to "rename1" then the code works.
#include <iostream>
using namespace std;
class feature { // this class has a specific feature
private:
char data[16];
public:
feature() { strcpy(data, "default"); }
feature(char * in) { strcpy(data, in); } // error checks needed
void set(char * in) { strcpy(data, in); }
void out() { cout << data << endl; }
};
class rename1 : private feature {
public:
void reset(char * in) { set(in); }
void print() { out(); }
rename1() : feature() {}
rename1(char * in) : feature(in) {}
};
int main() {
feature test1;
feature test2("test2 data");
rename1 test3;
rename1 test4("test4 data");
test1.out();
test2.out();
test3.print();
test4.print();
}
rename is a function that gets included by the header <cstring> in Visual Studio, which causes a conflict with the name of your class. You therefore need to change the name of your derived class. Visual Studio will probably also require you to change strcpy to strcpy_s (it may either give a Warning or Error otherwise).
Ideally you should avoid using C compatibility headers in new code you write (unless you absolutely need them), e.g.: in your example you should stick to std::string instead of char*
Related
I'm making a car design program. For this program, we are making a class in a header file, and then we will use that header file in our main program by including the file using #include "name of header".
This is my professors header. This is the code in his header. We were instructed to do the header like he is.
/*
Program 14-2
author - Ray Warren, modified from Language Companion
last updated - 19 July 2013
*/
#include <string>
using namespace std;
class CellPhone
{
private:
// Field declarations
string manufacturer;
string modelNumber;
double retailPrice;
public:
// Constructor
CellPhone(string manufact, string modNum, double retail)
{
manufacturer = manufact;
modelNumber = modNum;
retailPrice = retail;
}
// Member functions
void setManufacturer(string manufact)
{
manufacturer = manufact;
}
void setModelNumber(string modNum)
{
modelNumber = modNum;
}
void setRetailPrice(double retail)
{
retailPrice = retail;
}
string getManufacturer()
{
return manufacturer;
}
string getModelNumber()
{
return modelNumber;
}
double getRetailPrice()
{
return retailPrice;
}
}; //end class
This is the program he used the header file in (as you see he included the header file).
/*
Program14-2
author - Ray Warren, modified from Language Companion
last updated - 19 July 2013
*/
#include <iostream>
#include <cstdlib>
#include "CellPhone.hpp"
using namespace std;
int main()
{
// Create a CellPhone object and initialize its
// fields with values passed to the constructor.
CellPhone myPhone("Motorola", "M1000", 199.99);
// Display the values stored in the fields.
cout << "The manufacturer is "
<< myPhone.getManufacturer() << endl;
cout << "The model number is "
<< myPhone.getModelNumber() << endl;
cout << "The retail price is "
<< myPhone.getRetailPrice() << endl;
system("Pause");
return 0;
} //end main
This is my header file containing my class.
#include <string>
using namespace std;
Car(int ym, string mk)
{
yearModel=ym;
make=mk;
speed=0;
}
void setYearModel(int ym)
{
yearModel=ym;
}
void setMake (string mk)
{
make=mk;
}
int returnYearModel()
{
return yearModel;
}
string returnMake()
{
return make;
}
int returnSpeed()
{
return speed;
}
void accelerate()
{
speed += 5;
}
void brake()
{
This is my main program with me attempting to include the header file into my main program. When I tried to compile this, my header file popped up in a new code blocks IDE tab, and gave me this list of errors.
http://prntscr.com/bzu4x5 <--------- list of errors
I have no idea what I'm doing wrong. From what I see, I copied my professor exactly as he told us to, and I'm still getting errors.
Does anyone have any ideas of what's causing this massive list of errors?
#include <string>
#include <iostream>
#include "Car header.h"
int main()
{
}
Your "header file" contains the definitions of the class member functions. It should actually be a .cpp file. What you are missing is a definition of the class itself, and declarations of the member functions.
Note that your professor's sample header file defines the member functions inside the class definition. This is actually poor practise, but he may not have got round to teaching you how do define functions out of line yet.
If you are going to define the functions out of line, you will also need to change the functions to some thing like:
std::string Car::returnMake()
{
return make;
}
Note: "using namespace std" is also poor practise. Professional C++ code tends to be explicit, and use the "std::" prefix. Just get in the habit and save yourself hours of pain.
You did not actually define a class in you header file. Notice that in your teacher's header file, he has:
class Cellphone // -> this is what you do not have
{
private:
// Field declarations
string manufacturer;
string modelNumber;
double retailPrice;
public:
//constructor function
CellPhone(string manufact, string modNum, double retail);
// Member functions
void setManufacturer(string manufact);
void setModelNumber(string modNum);
void setRetailPrice(double retail);
string getManufacturer();
string getModelNumber();
double getRetailPrice();
}
You should have you fields and member functions inside your class. Hope that helps
I have spent a great deal of time in google trying to figure out how to pass a vector when using .h and .cpp files between a call in main and a function in an includes block. I was successful using class definitions.
Now everything is going fine until I want to create an overloaded function. (I could have done this with two different classes, but I must use one overloaded function in my program.)
Here is my writeData.h file:
#ifndef WRITEDATA_H
#define WRITEDATA_H
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
class writeData
{
public: writeData();
public: writeData(vector<int> & DATAFILE);
public: writeData(vector<int> & DATAFILE, string);
};
#endif
The placement of the using namespace std; is another topic.
Here is my writeData.cpp file:
#include "writeData.h"
writeData::writeData()
{
std::cout << "Default writeData" << std::endl;
}
writeData::writeData(vector<int> & DATAFILE)
{
cout << "writeData 1" << endl;
for (int var : DATAFILE)
{
cout << var <<endl;
}
}
writeData::writeData(vector<int> & DATAFILE, string fileName)
{
ofstream myfile(fileName);
cout << "writeData" << endl;
if (myfile.is_open())
{
for (int var : DATAFILE)
{
cout << var << endl;
myfile << var << endl;
}
myfile.close();
}
}
And here is my main function:
#include <iostream>
#include <vector>
#include <string>
#include "writeData.h"
using namespace std;
int main()
{
string fileName = "test.txt";
vector<int> items{ 10, 14, 22, 34 };
writeData();//default
///////////////////////////////////////////////////
// the next line is the problem code:
//writeData(items);//writes to screen only
//<<When I uncomment it the compiler Tosses the following:
// 'items': redefinition; different basic types
////////////////////////////////////////////////////
writeData(items, fileName);//writes to screen and to file
cin.ignore();
cin.get();
}
The offending line is writeData(items);
Any assistance or pointers to online articles would be most appreciated.
The immediate issue is that this declaration
writeData(items);
is the same as
writeData items;
hence the redefinition error. The deeper issue is that you have defined three constructors for a class, and seem to be attempting to call them without making a named instance. To succesfully call the one parameter constructor passing items, you'd need something like
writeData data_writer(items);
Alternatively, you may want either member functions, or non-members. The choice would depend on whether you really want to model a class, which maintains certain invariants or not. An example of members,
class writeData
{
public:
void write_data() const;
void write_data(const vector<int> & DATAFILE) const;
void write_data(const vector<int> & DATAFILE, string) const;
};
Then
WriteData wd;
wd.write_data(items);
Example of non-members:
namespace writeData
{
void write_data();
void write_data(const vector<int> & DATAFILE);
void write_data(const vector<int> & DATAFILE, string);
};
Then
writeData::write_data(items);
Note I have made the vector<int> parameters const reference because they are not being moified in the functions.
I have listed my code below. I get soooo many errors saying cout and endl was not declared in this scope. I do not know what I am doing wrong or how to force the class to recognise cout? I hope I am explaining my problem correctly. If I comment out the methods (not the constructor) it works. I am probably just making a novice mistake here - please help.
using namespace std;
class SignatureDemo{
public:
SignatureDemo (int val):m_Val(val){}
void demo(int n){
cout<<++m_Val<<"\tdemo(int)"<<endl;
}
void demo(int n)const{
cout<<m_Val<<"\tdemo(int) const"<<endl;
}
void demo(short s){
cout<<++m_Val<<"\tdemo(short)"<<endl;
}
void demo(float f){
cout<<++m_Val<<"\tdemo(float)"<<endl;
}
void demo(float f) const{
cout<<m_Val<<"\tdemo(float) const"<<endl;
}
void demo(double d){
cout<<++m_Val<<"\tdemo(double)"<<endl;
}
private:
int m_Val;
};
int main()
{
SignatureDemo sd(5);
return 0;
}
The compiler needs to know where to find std::cout first. You just need to include the correct header file:
#include <iostream>
I'd suggest you not to pollute the namespace using using directives. Instead either learn to prefix std classes/objects with std:: or use specific using directives:
using std::cout;
using std::endl;
I'm getting a runtime error ("memory can't be written") that, after inspection through the debugger, leads to the warning in the tittle.
The headers are the following:
componente.h:
#ifndef COMPONENTE_H
#define COMPONENTE_H
using namespace std;
class componente
{
int num_piezas;
int codigo;
char* proovedor;
public:
componente();
componente(int a, int b, const char* c);
virtual ~componente();
virtual void print();
};
#endif // COMPONENTE_H
complement.h implementation
#include "Componente.h"
#include <string.h>
#include <iostream>
componente::componente()
{
num_piezas = 0;
codigo = 0;
strcpy(proovedor, "");
//ctor
}
componente::componente(int a = 0, int b = 0, const char* c = "")
{
num_piezas = a;
codigo = b;
strcpy(proovedor, "");
}
componente::~componente()
{
delete proovedor;//dtor
}
void componente::print()
{
cout << "Proovedor: " << proovedor << endl;
cout << "Piezas: " << num_piezas << endl;
cout << "Codigo: " << codigo << endl;
}
teclado.h
#ifndef TECLADO_H
#define TECLADO_H
#include "Componente.h"
class teclado : public componente
{
int teclas;
public:
teclado();
teclado(int a, int b, int c, char* d);
virtual ~teclado();
void print();
};
#endif // TECLADO_H
teclado.h implementation
#include "teclado.h"
#include <iostream>
teclado::teclado() : componente()
{
teclas = 0;//ctor
}
teclado::~teclado()
{
teclas = 0;//dtor
}
teclado::teclado(int a = 0, int b = 0, int c = 0, char* d = "") : componente(a,b,d)
{
teclas = c;
}
void teclado::print()
{
cout << "Teclas: " << teclas << endl;
}
The main method where I get the runtime error is the following:
#include <iostream>
#include "teclado.h"
using namespace std;
int main()
{
componente a; // here I have the breakpoint where I check this warning
a.print();
return 0;
}
BUT, if instead of creating an "componente" object, I create a "teclado" object, I don't get the runtime error. I STILL get the warning during debugging, but the program behaves as expected:
#include <iostream>
#include "teclado.h"
using namespace std;
int main()
{
teclado a;
a.print();
return 0;
}
This returns "Teclas = 0" plus the "Press any key..." thing.
Do you have any idea why the linker is having troube with this? It doesn't show up when I invoke the virtual function, but before, during construction.
Two errors that I can see:
strcpy(proovedor, ""); // No memory has been allocated to `proovedor` and
// it is uninitialised.
As it is uninitialised this could be overwriting anywhere in the process memory, so could be corrupting the virtual table.
You could change this to (in both constructors):
proovedor = strdup("");
Destructor uses incorrect delete on proovedor:
delete proovedor; // should be delete[] proovedor
As this is C++ you should considering using std::string instead of char*.
If you do not change to std::string then you need to either:
Implement a copy constructor and assignment operator as the default versions are incorrect if you have a member variable that is dynamically allocated, or
Make the copy constructor and assignment operator private to make it impossible for them to be used.
Another source of this same message is that gdb can get confused by not-yet-initialized variables. (This answers the question title, but not the OP's question, since a web search led me here looking for an answer.)
Naturally, you shouldn't have uninitialized variables, but in my case gdb attempts to show function local variables even before they are declared/initialized.
Today I'm stepping through another developer's gtest case and this message was getting dumped to output every time the debugger stopped. In this case, the variable in question was declared on ~line 245, but the function started on ~line 202. Every time I stopped the debugger between these lines, I received the message.
I worked around the issue by moving the variable declaration to the top of the function.
For reference, I am testing with gdb version 7.11.1 in QtCreator 4.1.0 and I compiled with g++ version 5.4.1
I have following code, which i taken from Boost and simplified for my project. Please accept my aplogies for pasting complete code, i done it so that it will be easy to answer my question. While compiling following code in VS 2008 i am getting followoing error.
error C2064: term does not evaluate to a function taking 3 arguments
I am expecting addOptions retruns OptionsInit object which call function operator with three arguments but that is not happening, can any one please find bug. Thanks in advance.
namespace MyInfrastructure
{
namespace Internal
{
class OptionDescrp;
class OptionsInit;
}
class OptionsCollection
{
public:
OptionsCollection(std::string optCollName);
Internal::OptionsInit addOptions();
private:
// avoid copying and assignment.
// Prohibit copy
OptionsCollection( const OptionsCollection& );
OptionsCollection& operator = (const OptionsCollection& );
void add(Internal::OptionDescrp* desc) {m_options.push_back(desc);}
std::vector<Internal::OptionDescrp* > m_options;
std::string m_optCollName;
friend class Internal::OptionsInit;
};
}
////////////
#include <string>
#include <vector>
#include <assert.h>
#include "PrgmOptions.h"
namespace MyInfrastructure
{
namespace Internal
{
class OptionDescrp
{
public:
OptionDescrp(std::string pcOptname, std::string description, bool isOptValueReq);
virtual ~OptionDescrp(){ };
private:
std::string m_shortName; // option short name.
std::string m_longName; // option long name.
std::string m_description;// option description.
};
class OptionsInit
{
public:
OptionsInit(OptionsCollection* coll){ owner = coll; }
OptionsInit& operator()(std::string name, std::string description, bool isOptValReq);
private:
OptionsCollection* owner;
};
}
/////
namespace MyInfrastructure
{
OptionsCollection::OptionsCollection(std::string optCollName) : m_optCollName(optCollName) {}
Internal::OptionsInit OptionsCollection::addOptions()
{
return Internal::OptionsInit(this);
}
}
namespace MyInfrastructure
{
namespace Internal
{
// Class Options description definitions.
OptionDescrp::OptionDescrp(std::string pcOptname, std::string description, bool isOptValueReq)
: m_description(description)
{
std::string name(pcOptname);
std::string::size_type n = name.find(',');
if (n != std::string::npos)
{
assert(n == name.size()-2);
m_longName = name.substr(0, n);
m_shortName = '-' + name.substr(n+1,1);
}
else
{
m_longName = name;
}
}
// Class Options Init definitions.
OptionsInit& OptionsInit::operator()(std::string name, std::string description, bool isOptValReq)
{
OptionDescrp* opt = new OptionDescrp(name, description, isOptValReq);
owner->add(opt);
return *this;
}
}
}
//////
int main(void)
{
MyInfrastructure::OptionsCollection desc("myoptions");
**desc.addOptions()("help", "produce help message", false); // error is thrown here**
return 0;
}
The example code in the question compiles without errors with Visual 2008, gcc, Visual 2003 when we copy all in a single file.
You have error C2064, it is probably because you either have a #define or another definition somewhere in other headers that you did not include in your sample, or that somehow you are not compiling exactly the sample code.
Try to copy all the sample code in a single file and compile that.
Interesting code: OptionsInit returned by addOptions() is a temporary. You are then calling a non-const method on it, which is allowed, but it returns a non-const reference to itself which is also allowed because it's a non-const method. But that means essentially you "backdoor" binding a non-const reference to a temporary...
I assume the two asterisks before desc.addOptions are not really in your code as there is no operator* overloaded here.
Perhaps if you make operator() const and return const-reference it will work.
problem is with VS2008. I compiled with VS2010, it compiled fine. Thanks all for the inputs.