Use a struct from a object? [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 8 years ago.
Improve this question
I started with working code (not written by me obviously), I saw them make a class object dataflash which made sense to me, but then after that they used:
DataFlash::ID id;
Which is obviously because they needed an object of that struct, but the fact they went back to the DataFlash class bugged me, not sure why, but I thought "No, no, you should be using the object we just made now" and promptly changed it to what I have below, which produces the following error:
error: invalid use of ‘struct main()::DataFlash::ID’
Well that's no fair, I'm basically doing the same thing to my eye, why is this invalid use? Are structs (and nested classes I assume too) useless once they are in an object?
#include <iostream>
using namespace std;
int main()
{
class DataFlash
{
public:
struct ID
{
uint8_t manufacturer; /**< Manufacturer id **/
uint8_t device[2]; /**< Device id **/
uint8_t extendedInfoLength; /**< Extended device information**/
};
};
DataFlash dataflash;
dataflash.ID id;
return 0;
}

The code defines several layers of nested scope, the original code is doing scope resolution with the scope resolution operator ::
Your example uses a member access operator . and the struct ID simply is not a member, it lives in the scope of your type, a type and value is not the same thing.
As a footnote, enumerations can be accessed in both ways due to enum's scoping rules.
#include <iostream>
struct object {
enum identifier {
a = 2,
b = 16,
};
identifier id;
};
int main(int argc, char* argv[]) {
object obj;
std::cout << object::a << std::endl;
std::cout << obj.b << std::endl;
}

Related

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.

This member function is not getting called, and I can't figure out how to rectify it [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 3 years ago.
Improve this question
I'm reading through my C++ textbook for an upcoming class, and following along an exercise in the book. This exercise compiles and seems to give the results that you would expect, but it seems there is an error though, and I can't figure out how to fix it.
Here is the code.
// Page 706 from text
//Contents of ThisExample.h
class Example
{
int x;
public:
Example(int a){x=a;}
void setValue(int);
void printAddressAndValue();
};
/*
//Contents of ThisExample.cpp
#include "ThisExample.h"
*/
#include <iostream>
using namespace std;
/*********************************************************
* Set value of object.
*********************************************************/
void Example::setValue(int a) // <---------- Doesn't execute
{ // <---------- Doesn't execute
x = a; // <---------- Doesn't execute
} // <---------- Doesn't execute
void Example::printAddressAndValue()
{
cout<< "The object at address " << this << " has "
<< "value "<< (*this).x<<endl;
}
/*
//Contents of main program
#include <iostream>
#include "ThisExample.h"
using namespace std;
*/
int main()
{
Example ob1(10), ob2(20);
// Print the addresses of the two objects
cout<<"Addresses of objects are "<< &ob1 << " and "<<&ob2<<endl;
// Print the addresses and values from within the member function
ob1.printAddressAndValue();
ob2.printAddressAndValue();
return 0;
}
In the book, they talk about replacing
void Example::setValue(int a)
{
x = a;
}
with
void Example::setValue(int a)
{
this->x = x;
}
But when I step through it with a debugger (which I am also new to), I don't see that function ever getting called.
I've tried commenting out the function entirely and it still runs, that's how I know it isn't getting called.
I also tried removing from the class
Example(int a){x=a;}
but then it doesn't compile. Any help? I just want to move along with the textbook, which is called "Starting Out With C++ Early Objects
Judy Walters, Godfrey Muganda, Tony Gaddis" and the exercise is on page 706.
Thanks
It doesn't ever get called, because you never call it.
The only place that the member variable x is set, in this particular example, is in the constructor. And the constructor happens to do so directly, rather than by calling setValue().
You could later call setValue() to change x, but currently you do not.
It's not uncommon to provide functionality that makes sense to be part of the class, even if you're not using that functionality quite yet. Although, unless you're writing a library, you generally wouldn't do too much of writing functionality you don't yet need.
Perhaps later exercises in the textbook involve calling setValue(). I would just continue reading and not worry about this.

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.

Initialializing a struct with predefined values [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 7 years ago.
Improve this question
#include <iostream>
using namespace std;
int main()
{
struct naming
{
int numline;
string numname;
} naming = {{1,"ONE"},{2,"TWO"}};
cout<<naming.numline<<":"<<naming.numname<<std::endl;
return 0;
}
This error occurs:
main.cpp:10:33: error: braces around scalar initializer for type int
} naming = {{1,"ONE"},{2,"TWO"}};
You have
struct naming { … } naming = …
which means you're creating a single naming object. But your initializer
{{1,"ONE"},{2,"TWO"}}
doesn't match that intent.
Looks like you're trying to initialize a collection of naming objects. If that's the case you should make it a std::vector<naming> instead of a single object:
struct naming { … }; // definition of naming
std::vector<naming> namings = {{1, "ONE"}, {2, "TWO"}}; // collection of objects
Then you can access the individual naming objects like so:
// access the first element:
std::cout << namings.at(0).numline << ":" << namings.at(0).numname << std::endl;
// access the second element:
std::cout << namings.at(1).numline << ":" << namings.at(1).numname << std::endl;
Since you want to store two values , you will have to create an array of structure type.
#include <iostream>
using namespace std;
int main()
{
struct naming
{
int numline;
string numname;
} naming[] = {{1,"ONE"},{2,"TWO"}};
cout<<naming[0].numline<<":"<<naming[0].numname<<std::endl;
cout<<naming[1].numline<<":"<<naming[1].numname<<std::endl;
return 0;
}

Why is the vptr discarded when I copy objects? [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 9 years ago.
Improve this question
Example
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <iomanip>
struct father
{
int variable;
father(){variable=0xEEEEEEEE;};
virtual void sing(){printf("trollolo,%x\n",variable);}
~father(){};
};
struct son:father
{
son(){variable=0xDDDDDDDD;};
virtual void sing(){printf("trillili,%x\n",variable);}
~son(){};
};
int main()
{
father * ifather=new(father);
son * ison=new(son);
father uncle;
father * iteachers;
*((long long*)&uncle)=0xDEAF;
iteachers=(father*)malloc(20*sizeof(father));
//ineffective assignments
iteachers[0]=*ifather;
uncle=*ifather;
ifather->sing();//called to prevent optimization
ison->sing();//only to prevent optimization
std::cout.setf(std::ios::hex);
std::cout<<"father:"<<*((long long*)ifather)<<","<<std::endl;
std::cout<<"teacher0:"<<*((long long*)&(iteachers[0]))<<","<<std::endl;
std::cout<<"uncle:"<<*((long long*)&uncle)<<","<<std::endl;
std::cout<<"(son:"<<*((long long*)ison)<<"),"<<std::endl;
// uncle.sing();//would crash
}
The vtable pointer of teachers[0] is zero when compiled with gcc.
Also the vtable pointer of uncle keeps its original value instead of being overwritten.
My questions: Why HAS it be that way?
Is there a CLEAN workaround? Can i go with uncle._vptr=ifather->_vptr and still be portable? What is the ORDINARY routine to copy an object? Should I even file a bug?
Note: it should copy the whole object platform-independant, because no matter how the identification of the object type is done, since it should always be inside the object's data block!
The article
Why does my C++ object loses its VPTr
didn't help me, that must have a different reason.
As I understand it, basically the question is whether this code:
#include <iostream>
using namespace std;
struct Base
{
virtual void sing() { cout << "Base!" << endl; }
virtual ~Base() {}
};
struct Derived: Base
{
void sing() override { cout << "Derived!" << endl; }
};
auto main()
-> int
{
Base* p = new Derived();
*p = Base();
p->sing(); // Reporting "Base" or "Derived"?
}
should report "Base" or "Derived".
In short, assignment does not change the type of an object.
Hence, it reports "Derived".