Using pointers with classes in C++ [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am familiar with creating classes and using dot notations to access functions for the objects. I am unfamiliar with the notation of doing the same but with pointers. Please take a look at my code and suggest how I change the code in the class definition, not main.
main:
Pet * p = new Pet( "Sunset", "Cat", "meow..." );
cout << "The " << p->getVariety( ) << " " << p->getName( ) << " speaks by saying " << p->spea( ) << endl;
class:
class Pet
{
public:
Pet( );
Pet( std::string name, std::string variety, std::string says )
{
using namespace std;
myName = name;
myVariety = variety;
howIspeak = says;
}
std::string getName( ) const
{
return myName;
};
std::string getVariety( ) const
{
return myVariety;
};
virtual void speak( );
protected:
std::string myName;
std::string myVariety;
std::string howIspeak;
};

I guess, it's the
virtual void speak( );
in
cout << "The " << "..." << p->speak( ) << endl;
which causes the error message. You cannot output a void value to std::ostream.
Presumably, it should have been
virtual std::string speak();

Please take a look at my code and suggest how I change the code in the class definition, not main.
The using namespace std; is useless in there, just remove it.
Then, you are having virtual methods and protected members, which suggests that you are willing to inherit from that class: either don't or define a virtual destructor as well.
Also, the speak member function you are calling from the main, returns void, which is not a type you want to pass to operator<< of std::cout.
And finally: why are you using nake pointers and dynamic allocation? Don't use it unless you are absolutely forced to, and even then, use std::shared_ptr or std::unique_ptr (or any other of the smart pointers family) instead:
std::unique_ptr<Pet> ptr(new Pet( "Sunset", "Cat", "meow..." ));
After that line, ptr will behave almost like any other pointer, except it will clean himself up (will call delete) when you are done with it (when it leaves the scope).

I would suggest reading an introductory book on C++, "C++ Primer (4th Edition)" by Lippmann et al. or finding an on-line tutorial on C++. The problem you are solving requires more understanding than can be related in an SO Q and A.

Related

String in a class [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I was working on a project and I've had a question: when I call a class that contain a string str, does the code create a string every time or it use the string I've already created?
For example:
#include <iostream>
using namespace std;
class exClass {
public:
void exVoid ( string valueStr )
{
str = "Hi";
cout << str;
}
private:
string str;
};
int main()
{
exClass myClass;
string stringMain;
while (1)
{
cout << "Insert value of str: ";
cin >> stringMain;
myClass.exVoid(stringMain);
}
}
so the question is: every time I call exClass, the class create the string str or it do that only once (when I call it for the first time)?
Following the flow of the program:
First you create an instance of exClass named myClass. This happens once.
Then you create a string named stringMain. This also happens once.
After that, you have an endless loop while(1). Inside this loop you:
Print on the output
Get input
Call function exVoid()
So, you create one instance of class exClass with one member str and use the same str (through your function) endlessly inside your loop.
Something to think about is the function argument. You never really use it. For it to have meaning in you code, you can do something like:
void exVoid ( string valueStr )
{
str = valueStr;
cout << str;
}
Yes, you're creating a copy of your input string every time you call exVoid. You can make it more efficient if you use a reference:
void exVoid(const std::string &value) {
...
}
The way you're calling it from main, you're thus passing a reference to stringMain, but by making it const, you know your method won't mess with it.

Is static_cast creating new child object? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
This code runs fine, when it should have a run-time error, since i haven't instantiated a derived class object.
#include <iostream>
using namespace std;
class Person {
public:
void walk() { cout << "person walking" << endl; }
};
class Employee :public Person {
public:
void work() { cout << "employee working" << endl; }
};
void main() {
Person* p = new Person();
Employee* e = static_cast<Employee*>(p);
e->work();// this is working - but why? it should fail at runtime
}
If static_cast only casting the pointer, how is it possible to call a child member function?
At what point is the child instantiated?
Is static_cast also instantiating objects?
No.
Your assertion that your code should "crash at runtime" is, unfortunately, wrong. Your code exhibits undefined behaviour meaning that it could do literally anything. In this case I expect it works because the address of the function is the same in both objects but really, it could be for any reason.

accessing private members without using friend class [duplicate]

This question already has answers here:
Can I access private members from outside the class without using friends?
(27 answers)
Closed 2 years ago.
I have a homework in which:
we have this code:
#include <iostream>
using namespace std;
class Test {
int x;
char y;
public:
Test() :x(0), y(0) { ; }
};
int main() {
Test t;
//Do stuff!
return 0;
}
and without adding getters and setters or using friend class we have to read x and y and also change them.
I searched and found these ways:
if there was a template function in my class I could say:
class Test {
int x;
char y;
public:
Test() :x(0), y(0) { ; }
template<typename T>
void do_something() {//not necessarily void function
//Do some stuff
};
};
class a;
// My specialization.
template <>
void Test::do_something<a>() {
cout << x << endl;
cout << y << endl;
// getting data
x = 5;
y = 'a';
// changing data
cout << x << endl;
cout << y << endl;
// getting data after changes we made
}
int main() {
Test t;
t.do_something<a>();
return 0;
}
and also the method, which I think is this question answer, is using pointers.
like this:
class Test {
int x;
char y;
public:
Test() :x(0), y('0') { ; }
};
int main() {
Test t;
int* ptr = (int*)&t;
cout << "x = " << *ptr << " y = " << (char)*(ptr + 1) << endl;
*ptr--;
//getting data
*ptr = 12;
ptr++;
*ptr = 65;
//changing data
ptr--;
cout << "x = " << *ptr << " y = " << (char)*(ptr + 1) << endl;
//getting data after changes we have made
return 0;
}
or using reinterpret_cast and pointers:
struct pointer {
int x;
char y;
};
class Test {
int x;
char y;
public:
Test() :x(0), y('0') { ; }
};
int main()
{
Test t;
pointer* p = reinterpret_cast<pointer*>(&t);
cout << "X = " << p->x << " Y = " << p->y << endl;
//getting data
p->x = 5;
p->y = 'a';
//changing data
cout << "X = " << p->x << " Y = " << p->y << endl;
//getting data from class after changing them with pointers
return 0;
}
my questions are:
is such thing possible in other object oriented languages?
does this mean access modifiers are useless?
and is there anything we can do to prevent such thing to happen?
(with pointers) why this happen?
I don't understand this one, so I will skip it.
is such thing possible in other object oriented languages?
Consider python. In python making something private is explicitly only an agreement between the author and the user, but nothing prevents a user from accessing private members. Though, they should not. C++ isn't that explicit about saying "if you want you can access private members", but still it is possible with some effort. Nevertheless you should not. C++ does not prevent you from shooting yourself in your foot and accessing private members is one way of doing that. It isn't the case in your example, but typically accessing private members directly will break the object beyond repair.
does this mean access modifiers are useless?
I'll repeat my comment: Is a traffic light useless? I mean when it is red I can still cross the street. Access specifiers are not there to prevent you from doing something wrong by all means, they are to help you to avoid doing something wrong (and if you try hard you can still do something wrong).
and is there anything we can do to prevent such thing to happen?
Declaring a member as private is enough to signal that a user should not access the member directly by any means. If someone wants to break that agreement then they can do it. You cannot prevent a user from doing something wrong. If they want to break your class they can do so. However, it is not your responsibility to guarantee that something broken still works as expected. If a user bypasses access specifiers then they broke the agreement between them and you. Consider you buy a laptop and throw it out of the window from 42th floor. Will you complain to the manufacturer that afterwards the laptop is not working properly anymore? I guess no, instead you will understand that you made something wrong with using your laptop.
PS: Your last two examples are undefined behavior. reinterpret_cast is not a way to cast between arbitrary types magically. The set of allowed casts and what you can do with the results is in fact rather limited (see here). Also a c-style cast enables you do to casts that can be very wrong, without your compiler complaining about it. Thats why they should be avoided in favor of the proper c++ casts (static_cast et al).
Answering your question 4, is there anything we can do to prevent such thing to happen?:
It is indeed a language design problem that code using a class in C++ is typically able to see the inner makeup of a class. A visible, complete class definition is clearly a breach of information hiding. It's necessary though because of the "by-value semantics" of C++ that it inherited from C and which distinguishes it from, say, C# or Java.
One of the consequences is what you describe: That users can easier access object data they are not opposed to. (To be fair, with enough malicious energy that is unpreventable in the general sense no matter the precautions, but knowing the class layout allows you to do so with less "criminal effort", in this case through normal language means. Another, even simpler way which I recall was buried in one large project when it went open source was to simply #define private public before including the header in question.)
A second, more relevant problem is that code which uses objects of that class, or one of its descendants, is too tightly coupled with that class; it knows more than it should or needs to. Any trivial change to the class makes it necessary to recompile all code which includes its definition, directly or indirectly. For large projects with elaborate class hierarchies touching a base class may cause a senseless re-build of the whole project.1
To finally answer your question: The canonical C++ strategy to reduce this coupling are compilation firewalls. You essentially define an interface of pure virtual functions and no data, which should be relatively stable. User code sees only that interface. By that you gain information hiding and the power of polymorphism. But because you cannot directly handle objects any longer but only pointers or references, you lose the advantages of C++'s by-value paradigm (speed, no aliasing).
1 In a job interview in 1998 or so as C++ developer at Star Division, which was developing StarOffice, the original precursor to OpenOffice and LibreOffice, I was asked: "You have a base class, directly or indirectly used throughout the project. Now you would like to add a virtual function to it but avoid recompilation of the whole project, because it would just take too long. Can you do that? How?" The answer is that most implementations probably maintain the virtual functions in a vtable to which you can append without changing the offsets of existing functions (and, of course, without altering the object layout). Obviously, there is no guarantee that the implementation does not generate the vtable backwards, or employs some other mechanism, but in practice that's what you can do.

How to access and store item by vector with multiple class in C++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I want to use vector to store all Record. The Record class contains student and their age. It supposes to get the command and then call the specific method. However, when I compile it, it said "t is not declared". However, I have already declared as table t. How can I access the private vector without changing the visibility.
class student{
public:
int id;
string name;
student();
student(int,string);
};
class Record{
public:
student student;
int age;
};
class table{
public:
void Insert(student x,int y);
void Print(table t)
private:
vector <Record> records;
};
void Insert(student x,int y){
Record r;
r.student=x;
r.grade=y;
t.records.push_back(r);
}
void Print(table t){
sort( t.record.begin() , t.record.end() );
vector<Record>::iterator itr;
for( itr = t.record.begin() ; itr != t.record.end() ; itr++ )
cout << (*itr).student.id << '\t' << (*itr).student.name << '\t' << (*itr).age << endl;
}
int main (){
student x;
table t;
string command,name;
int id,age;
while ( cin >> command ){
if (command=="Insert"){
cin >> id >> name>> grade;
student s(id,name);
t.InsertStudent(s,grade);
}else if (command == "Print"){
t.Print(t);
}else{return 0;
}
}
The error message is:
t was not declared in this scope in t.records.push_back(r);
I have capitalized the class name and the problem still exist.
There are a significant number of problems with this code. So we'll address the 3 mistakes most closely related to your question: How can I access the private vector without changing the visibility?
You are calling: t.InsertStudent(s,grade). Since you declare table t, that will try to call class table's InsertStudent method. Which there isn't one. You probably intended to call the Insert method.
You define the function void Insert(student x,int y) which was likely intended as the method void table::Insert(student, int y). Note the class scoping on the definition. Alternatively, you could remove the declaration, and just use the definition directly in class scope.
You are trying to call t.records.push_back(r) where t is not a global object that this function would have access to. But presuming from 2 that you intended to define this as a method you would not use an object name to access member variables, instead you could directly access the member variables: records.push_back(r)
I've tried to briefly explain how to fix stuff, but there are some underlying conceptual problems here that need to be addressed, which probably can't be addressed in a couple sentences. Please at least read through: http://www.cplusplus.com/doc/tutorial/classes/ before asking follow up questions. If any of my answer remains unclear after reading through that, feel free to comment below.
As far as other errors in the code start by looking over the line that the compiler issues the waning on. If you can't solve it using that feel free to open a new question posting the code and error.

How to understand the C++ implicit parameter "this" [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
if we create a class like this :
class Sales_data
{
std::string isbn() const {return bookNo;}
std::string bookNo;
};
And we make a object total;
Sales_data total;
total.isbn();
The C++ Primer, fifth edition, says (page 258),"when we call a member function, this is initialized with the address of the object on which the function was invoked "
,it like this:
Sales_data::isbn(&total)
and the book also write,we can get the bookNo like :
std::string isbn()const {return this->bookNo;}
I think the implicit parameter "this" just like a pointer,
but i can't see it type,would anybody help me point what wrong i think and what should i do to understand the implicit parameter 'this' and this parameter works for?
#Jason C
my extra question:
this is a pointer,so it behave like a normal pointer,
#include "iostream"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int a = 1;
int * b = &a;
cout << "the b is " << b << endl;
cout << "the &a is " << &a << endl;
cout << "the *b is " << *b << endl;
cout << "the &b is" << &b << endl;
return 0;
}
on my computer the output is :
the b is 0110FCEC
the &a is 0110FCEC
the *b is 1
the &b is0110FCE0
then ,What's the use of the type of the pointer.
this is not a parameter, it is a way for an object to refer to itself.
If you use visual studio or any modern IDE you can check that this has the same type as the class of which it is a member of.
There is a good book called "The C++ Object Model" by Stanley B. Lippman which can help understand.
Even if not defined as such in the standard, every implementation I am aware of makes this an implicit parameter to a member function and can be viewed as such.
In C++, you do
object->function () ;
In contrast, in Ada the syntax is
function (object) ;
The object is then an explicit parameter to the member function. The this variable is a product of C++'s member calling syntax. Instead of the programmer having to explicitly declare a parameter identifying the object (as in Ada), C++ does this automatically for you (this).
In most implementations, C++ parameters are bound to offsets to locations on the stack or to registers. This is implemented in the very same way as other parameters (either bound to a stack offset or a register).
this is a pointer to whatever instance of an object the member function is being called on (note that there is no this in static member functions or non-member functions, then).
In your case, it is either a Sales_data * or const Sales_data * depending on the context. Inside isbn(), it is the latter.
This (contrived) example illustrates its value:
class Example {
public:
void function (Example *x);
};
void Example::function (Example *x) {
if (x == this)
cout << "x is this!" << endl;
else
cout << "x is not this." << endl;
}
Now if we do:
Example a;
Example *b = new Example();
a.function(&a); // outputs "x is this!"
b->function(b); // outputs "x is this!"
a.function(b); // outputs "x is not this!"
b->function(&a); // outputs "x is not this!"
Also, since it's a pointer to the "current" instance of the object:
class Example2 {
public:
int k;
void function ();
};
void Example2::function () {
k = 42;
this->k = 42; // does the same thing as above!
}