I have 3 classes.
class piesa_a{
protected:
int id;
char *tip;
int pret;
public:
[custructor with/without param, display function - works well each one of it]
class piesa_b:public piesa_a
{
private:
float lungime;
bool bw;
public:
[custructor with/without param, display function - works well each one of it]
class piesa_c:public piesa_a
{
private:
int nr;
piesa_b *buf;
public:
piesa_c():piesa_a(){nr=0; buf = new piesa_b[nr];}
piesa_c(int n, piesa_b *bu,int aid, char *tipi, int pretzz):piesa_a(aid,tipi,pretzz)
{
buf = new piesa_b[nr];
for(int i=0;i<nr;i++)
buf[i]= bu[i];
}
void afisare()
{
cout<<nr;
}
In main i have this:
piesa_c C(2, H,14,"TIPC",20);
C.afisare();
But this doesn't work.
I don't know if the "buf" was declared properly because the problem seems to be in last class.
Why?
Later Edit:
The entire code is here: http://pastebin.com/nx2FGSfe.
Now, i have this in main
int main(int argc, char** argv) {
piesa_b *H;
H = new piesa_b[2];
piesa_a A(4,"TIPA",120);
piesa_b B(100,1,3,"TIPA",120);
H[0]=B;
H[1]=B;
piesa_c C(2, H,14,"TIPC",20);
piesa_a** v = new piesa_a*[3];
v[0] = &A;
v[1] = &B;
v[2] = &C;
for(int i=0;i<3;i++)
v[i].afisare();
return 0;
}
The display function return this error
main.cpp:143:14: error: request for member ‘afisare’ in ‘*(v + ((unsigned int)(((unsigned int)i) * 4u)))’, which is of non-class type ‘piesa_a*’
nr is not initialized in the piesa_c() constructor, meaning it will have an undefined value.
Instead of using a dynamically allocated array used a std::vector<piesa_b> instead. It will handle dynamic memory allocation and do the right thing when instances of piesa_c is copied. Using std::vector also means the nr member variable can omitted as that information can be obtained from vector::size() and the std::vector can be populated in the initializer list instead of in the constructor body:
std::vector<piesa_b> buf;
piesa_c(int n,
piesa_b *bu,
int aid,
char* tipi,
int pretzz) : piesa_a(aid,tipi,pretzz),
buf(bu, bu + nr) {}
And to invoke a member function on each element in buf:
// C++11 lambda, otherwise use
// std::vector<piesa_b>::const_iterator.
//
std::for_each(buf.begin(), buf.end(), [](piesa_b& pb) { pb.afisare(); });
If afisare() does not modify then make it const:
void afisare() const
{
}
Additonally, use std::string instead of char*. If you insist on having dynamically allocated members in the classes you need to obey the rule of three.
I am not sure what "not work" means in this context, but when you call this constructor:
piesa_c C(2, H,14,"TIPC",20);
the data member nr is not set. It can have any value that fits into an int, so when you use it to initialize an array you will get variable and weird results.
Note that you could save yourself a lot of trouble by using std::vector and std::string instead of dynamically allocated arrays and char*.
Related
If I create a two class members of char* type and is array. And if I resize first member of the class it overwrite the second member with same values.
Why it happens?
Is it some memory management issues?
#include <iostream>
using namespace std;
class myclass
{
private:
const char *arr1[0];
const char *arr2[4] {
"one",
"two",
"three",
"four"
};
public:
void run() {
int f = 0;
*this->arr1 = new char[4];
for(f = 0; f < 4; f++) {
this->arr1[f] = "foo";
}
for(f = 0; f < 4; f++) {
cout << this->arr2[f] << endl;
}
}
};
int main()
{
myclass *my = new myclass();
my->run();
return 0;
}
Output
foo
foo
foo
foo
const char *arr1[0];
Zero-sized arrays are not allowed in standard C++. Your compiler is allowing it as an extension to the language.
Even if your compiler has this extension, dereferencing an array of size 0 causes undefined behavior and you are doing this here:
*this->arr1 = new char[4];
I don't know what your intention here is, either you want
const char *arr1[4];
in which case *this->arr1 = new char[4]; is unnecessary or you want
const char **arr1;
in which case it should be this->arr1 = new const char*[4];.
You should not use char* to manage strings, use std::string instead, which does the memory management for you. Similarly, for multiple strings use std::vector<std::string> instead of char**.
There doesn't seem any reason to use dynamic memory allocation in main either. The same way as you should use std::vector to manage dynamically-sized arrays of objects instead of using new[]/delete[], don't use dynamic memory allocation to create single objects if you don't have a good reason for it and if you have to, use std::unique_ptr instead of raw new/delete.
int main()
{
myclass my;
my.run();
return 0;
}
This does the same without dynamic allocation.
So I'm looking for clarification on something that works. I'm pretty sure I understand what is happening but wanted to be sure before proceeding with my work.
I have a function defined as follows:
name* createName(char* firstName, char* lastName)
{
name* newName = (name*)malloc(sizeof(name));
initStringValue(&newName->firstName, firstName);
initStringValue(&newName->lastName, lastName);
newName->firstNameSize = strlen(newName->firstName);
newName->lastNameSize = strlen(newName->lastName);
return newName;
}
The structure "name" is defined like so:
struct name
{
char* firstName;
char* lastName;
int firstNameSize;
int lastNameSize;
};
Another function responsible for the copy of the name strings is written like the following:
void initStringValue(char** destination, char* source)
{
int length = strlen(source) + 1;
int size = length * sizeof(char);
*destination = (char*)malloc(size);
memset(*destination, 0, size);
strcpy(*destination, source);
}
If I'm understanding what I've done here, by using the & operator I've signified that I wish to send not a value but its associated memory address. In a statement such as
&newName->firstName
where the struct member firstName is a char* I've indicated that I would like to send the memory address of this pointer and not the pointers value (which happens to be a memory address in and of itself). The -> operator dereferences this pointer to the member of the pointer but then the & operator essentially returns us to the firstName memory reference instead, allowing me to manipulate information at that memory reference.
Now things get wild (for me anyway). To actually work with that memory reference, I end up using double indirection (so very passive aggressive). As it follows a memory reference (like that of &newName->firstName) sent to a char** like that of char** destination in the initStringValue function, would be a pointer of a pointer where the latter is assigned the memory reference returned by &newName->firstName. By then using *destination I'm working with a pointer pointed to the memory reference of &newName->firstName. Or stated differently, a pointer whose first and only member is the memory reference of newName->firstName.
Am I actually understanding this correctly?
Am I actually understanding this correctly?
After reading your description, I'll say yes
I'll try to explain it with some examples.
If you do this:
void foo(int a)
{
a = 5;
}
int main()
{
int a = 10;
foo(a);
printf("%d\n", a);
return 0;
}
You'll get the output: 10
That's because the function parameters are local variables to the function. In other words - any change made to a function parameter is lost when the function returns, i.e. the variable in main will not be changed.
If you want a function to change the value of a variable in main (aka in the caller), you'll have to pass a pointer. Like:
void foo(int* a) // notice int*
{
*a = 5; // notice *a
}
int main()
{
int a = 10;
foo(&a); // notice &a
printf("%d\n", a);
return 0;
}
This will output: 5
This is a general rule regardless of the type. I used int in the example but it applies to any type - pointers as well.
So let's take an example with a pointer:
void foo(char** a, int size) // notice char**
{
*a = malloc(32); // malloc memory
strcpy(*a, "Hello world"); // copy some data into the memory
}
int main()
{
char* a = NULL; // a is not pointing to anything yet
foo(&a);
// Now a points to the malloc'ed memory
printf("%s\n", a);
return 0;
}
This will output: Hello world
i am getting error in this code
class business
{
public:
business(); // Default Constructor
business(string busines,int r)
{
busines=busines;
ratings=r;
} // constructor;
private:
string busines;
int ratings;
int items_owned;
int business_cancellation;
int biz_size_of_building;
int biz_shipping_method;
};
int main(int argc, char *argv[])
{
business b[10];
b[b_count](busines,rating);
return 0;
}
It gives me the following error (http://ideone.com/FfajNS):
prog.cpp: In function ‘int main(int, char**)’:
prog.cpp:32:32: error: no match for call to ‘(business) (std::string&, int&)’
You're attempting to call a constructor on an already constructed object ... the default constructor was called during the array creation, therefore you cannot "construct" the object again. For your application, you may want to look into using a std::vector where you can create a array-like container using an object initialized from a set of default arguments.
For instance, you could do:
std::vector<business> array(10, business(business_string, rating));
I believe you want something like this:
b[2] = business("Denny's", 50);
This creates a temporary business variable by calling the constructor with the given parameters. The temporary is then copied into slot 3 of the array b.
The array b already created 10 business objects using the default constructor of that class. You can access those objects by business someBusiness = b[someIndex];
edit:
If you want to set the values of your individual objects, simply do this (notice, that you don't create these objects, just set their values):
for(int i=0; i<10; i++)
{
b[i].busines = ...;
b[i].ratings = ...;
/* or to create new ones */
b[i] = business("asd", 10);
}
It would be even better, if you stored these objects in vector, like Jason suggested
business b[10];
You create 10 "default" business object. What is b_count? I hope some int from 0 to 9.
But here you are "calling" a business object with 2 arguments:
b[b_count](busines,rating);
But business have no operator()() defined with 2 parametr.
EDIT:
You definitely have to use std::vector and carefully read the other answers.
But I know that on occasion beginners are not allowed to use the STL library, and anyway it seems that you should understand how constructors are used and how the elements of an array are initialized. Please read about static members and how they are defined and try to understand how the following example works.
#include <string>
using std::string;
class business
{
public:
business() // Default Constructor
:busines(def_busines),ratings(def_ratings){};
business(const string& bus,int r) // constructor;
:busines(bus),ratings(r){}
static void SetDef(const string& busines,int r)
{
def_busines=busines;
def_ratings=r;
}
private:
string busines;
int ratings;
static string def_busines;
static int def_ratings;
int items_owned;
int business_cancellation;
int biz_size_of_building;
int biz_shipping_method;
};
string business::def_busines=""; // Set here the default-defaults
int business::def_ratings=1;
int main(int argc, char *argv[])
{
business::SetDef("Some business",2);
business a[10];
business::SetDef("Other business",3);
business b[10];
business c("Third business",4);
return 0;
}
I want to make a function to allocate memory to an array. Suppose I have this:
PWSTR theStrings[] = { L"one", L"two", L"three" };
void foo(PWSTR a, int b) {
a=new PWSTR[b];
for(int i=0;i<b;i++) a[i]=L"hello";
return;
}
int main() {
foo(theStrings,4);
}
My question is, how do you make the function foo and the calling of that function so that after foo is called, theStrings will contain four "hello"
Thanks :)
Reinardus
There are two thing you must do to make this work:
Firstly, you must use a dynamically allocated array, rather than a statically allocated array. In particular, change the line
PSWTR theStrings[] = { L"one", L"two", L"three" };
into
PWSTR * theString = new PWSTR[3];
theString[0] = L"one";
theString[1] = L"two";
theString[2] = L"three";
This way, you're dealing with a pointer which can be modified to point to a different region of memory, as opposed to a static array, which utilized a fixed portion of memory.
Secondly, you're function should take either a pointer to a pointer, or a reference to a pointer. The two signatures look like this (respectively):
void foo(PWSTR ** a, int b); // pointer to pointer
void foo(PWSTR *& a, int b); // reference to pointer
The reference-to-pointer option is nice, since you can pretty much use your old code for foo:
void foo(PWSTR *& a, int b) {
a = new PWSTR[b];
for(int i=0;i<b;i++) a[i]=L"hello";
}
And the call to foo is still
foo(theStrings, 4);
So almost nothing must be changed.
With the pointer-to-pointer option, you must always dereference the a parameter:
void foo(PWST ** a, int b) {
*a = new PWSTR[b];
for(int i = 0; i<b; i++) (*a)[i] = L"hello";
}
And must call foo using the address-of operator:
foo(&theStrings, 4);
PWSTR theStrings[] = { L"one", L"two", L"three" };
void foo(PWSTR& a, int b) {
a=new PWSTR[b];
for(int i=0;i<b;i++) a[i]=L"hello";
return;
}
int main() {
PWSTR pStrings = theStrings;
foo(pStrings,4);
}
But instead of that, consider using std::vector and std::wstring and so on.
Also, anyway, consider using function result (the return) for function results, instead of in/out arguments.
Cheers & hth.,
If you are not required to use PWSTR then you can use std::vector< std::string > or std::valarray< std::string >.
If you want to store unicode strings (or wide characters) replace std::string with std::wstring.
You can see here on how to convert between CString/LPCTSTR/PWSTR to std::string: How to convert between various string types.
probably change it to something like
void foo(PWSTR * a, int b)
and
foo(&thestrings, 4);
I'm having this problem for quite a long time - I have fixed sized 2D array as a class member.
class myClass
{
public:
void getpointeM(...??????...);
double * retpointM();
private:
double M[3][3];
};
int main()
{
myClass moo;
double *A[3][3];
moo.getpointM( A ); ???
A = moo.retpointM(); ???
}
I'd like to pass pointer to M matrix outside. It's probably very simple, but I just can't find the proper combination of & and * etc.
Thanks for help.
double *A[3][3]; is a 2-dimensional array of double *s. You want double (*A)[3][3];
.
Then, note that A and *A and **A all have the same address, just different types.
Making a typedef can simplify things:
typedef double d3x3[3][3];
This being C++, you should pass the variable by reference, not pointer:
void getpointeM( d3x3 &matrix );
Now you don't need to use parens in type names, and the compiler makes sure you're passing an array of the correct size.
Your intent is not clear. What is getpointeM supposed to do? Return a pointer to the internal matrix (through the parameter), or return a copy of the matrix?
To return a pointer, you can do this
// Pointer-based version
...
void getpointeM(double (**p)[3][3]) { *p = &M; }
...
int main() {
double (*A)[3][3];
moo.getpointM(&A);
}
// Reference-based version
...
void getpointeM(double (*&p)[3][3]) { p = &M; }
...
int main() {
double (*A)[3][3];
moo.getpointM(A);
}
For retpointM the declaration would look as follows
...
double (*retpointM())[3][3] { return &M; }
...
int main() {
double (*A)[3][3];
A = moo.retpointM();
}
This is rather difficult to read though. You can make it look a lot clearer if you use a typedef-name for your array type
typedef double M3x3[3][3];
In that case the above examples will transform into
// Pointer-based version
...
void getpointeM(M3x3 **p) { *p = &M; }
...
int main() {
M3x3 *A;
moo.getpointM(&A);
}
// Reference-based version
...
void getpointeM(M3x3 *&p) { p = &M; }
...
int main() {
double (*A)[3][3];
moo.getpointM(A);
}
// retpointM
...
M3x3 *retpointM() { return &M; }
...
int main() {
M3x3 *A;
A = moo.retpointM();
}
The short answer is that you can get a double * to the start of the array:
public:
double * getMatrix() { return &M[0][0]; }
Outside the class, though, you can't really trivially turn the double * into another 2D array directly, at least not in a pattern that I've seen used.
You could create a 2D array in main, though (double A[3][3]) and pass that in to a getPoint method, which could copy the values into the passed-in array. That would give you a copy, which might be what you want (instead of the original, modifiable, data). Downside is that you have to copy it, of course.
class myClass
{
public:
void getpointeM(double *A[3][3])
{
//Initialize array here
}
private:
double M[3][3];
};
int main()
{
myClass moo;
double *A[3][3];
moo.getpointM( A );
}
You may want to take the code in your main function which works with the 2D array of doubles, and move that into myClass as a member function. Not only would you not have to deal with the difficulty of passing a pointer for that 2D array, but code external to your class would no longer need to know the details of how your class implements A, since they would now be calling a function in myClass and letting that do the work. If, say, you later decided to allow variable dimensions of A and chose to replace the array with a vector of vectors, you wouldn't need to rewrite any calling code in order for it to work.
In your main() function:
double *A[3][3];
creates a 3x3 array of double* (or pointers to doubles). In other words, 9 x 32-bit contiguous words of memory to store 9 memory pointers.
There's no need to make a copy of this array in main() unless the class is going to be destroyed, and you still want to access this information. Instead, you can simply return a pointer to the start of this member array.
If you only want to return a pointer to an internal class member, you only really need a single pointer value in main():
double *A;
But, if you're passing this pointer to a function and you need the function to update its value, you need a double pointer (which will allow the function to return the real pointer value back to the caller:
double **A;
And inside getpointM() you can simply point A to the internal member (M):
getpointeM(double** A)
{
// Updated types to make the assignment compatible
// This code will make the return argument (A) point to the
// memory location (&) of the start of the 2-dimensional array
// (M[0][0]).
*A = &(M[0][0]);
}
Make M public instead of private. Since you want to allow access to M through a pointer, M is not encapsulated anyway.
struct myClass {
myClass() {
std::fill_n(&M[0][0], sizeof M / sizeof M[0][0], 0.0);
}
double M[3][3];
};
int main() {
myClass moo;
double (*A)[3] = moo.M;
double (&R)[3][3] = moo.M;
for (int r = 0; r != 3; ++r) {
for (int c = 0; c != 3; ++c) {
cout << A[r][c] << R[r][c] << ' ';
// notice A[r][c] and R[r][c] are the exact same object
// I'm using both to show you can use A and R identically
}
}
return 0;
}
I would, in general, prefer R over A because the all of the lengths are fixed (A could potentially point to a double[10][3] if that was a requirement) and the reference will usually lead to clearer code.