0

EDIT

I am learning C++ through a series of questions from the university I attend. Here is an excerpt of the problem in question:

A retailer shop wishes to store information about its sales. Typical information it wishes to store about a sale are: Sale identification number (a unique number for each sale), customer’s surname and other names as well as the customer’s address. A sale can consist of up to 10 different items, with different quantities of each item. For each item, the sale class should store the item number, item description, unit cost and the number of units of the items purchased as well as the total cost for the item.


TLDR: I am trying to write a constructor for a class which contains an array as one of its attribute.

Background

I am learning about Classes in C++ and am currently trying out interface.

The Code

For the sake of clarity, here is a simplified version of the interface showing only the constructor:

Sale.h

class Sale {
    int* products_id[];

    public:
    Sale(int& products_id[]);
};

Now, the interface needs to be implemented:

Sale.cpp

#include "Sale.h"
Sale::Sale(int& product_id[]) {
    this->product_id[] = product_id[];
};

The Problem

  1. For some reasons, my IDE (VS Code) is complaining about an error

    no suitable conversion function from "product_id" to "product_id *" exists

  2. I am unable to find any relevant resources online.

I would appreciate it if someone could help me out or at least point me in the right direction. Regards.

Isfaaq
  • 415
  • 1
  • 4
  • 15
  • 5
    How are you learning C++? The `int* products_id[]` member and `int& products_id[]` make me thins that your resource for learning is doing you a disservice. Have you seen our [curated book list](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list), yet? – StoryTeller - Unslander Monica Feb 18 '19 at 07:11
  • There are several layers of problems here. The outermost (if we overlook the IDE vs. compiler thing) is that you are trying to assign an "integer" to a "pointer to integer". The next one is that you are accepting an array of references. The next on is that your syntax for assigning arrays is not C++. The next is that there is no such thing as assigning raw C arrays in C/C++. The next one is that you probably don't want an array of pointers as a class "attribute". The next one is that you are not allocating memory for your array. The next one is decaying of arrays to pointers (size!) And so on. – yzt Feb 18 '19 at 07:32
  • My suggestion is that you either go and learn about arrays and pointers and don't clutter up your program (and your learning experience) with this unnecessary OOP stuff, or go and learn/use `std::vector` and `std::array` and forget all about C arrays. Although, you will ***NEVER*** be able to advance in programming without understanding memory and object layout/lifetime. – yzt Feb 18 '19 at 07:35
  • @yzt I have edited the question. Kindly check it out. – Isfaaq Feb 18 '19 at 12:18

2 Answers2

1

First part: Pointer and C-Array

I guess you learned Java before writing such code snippet.

In Java, we have the handlers (or pointers to some extent) to each object, but in C++ we transmit objects directly by copying (without reference notation or redefinition of operator=). Therefore, the Java-style Type arr[] is misused in your code, and it has totally different meanings according to C/C++ contexts:

  1. Flexible array member which is only available in C99
  2. Just a pointer (not array) in function parameters
  3. Initializing an array without specifying the length directly
  4. Maybe more...

For instance:

#include <iostream>
using std::cout, std::endl;
int calc_sum(int arr[], int len) { // pointer
    int ans = 0;
    for (int i = 0; i < len; i++) {
        ans += arr[i];
    }
    return ans;
}
int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int n = sizeof(arr) / sizeof(int);
    cout << n << endl;
    cout << calc_sum(arr, n) << endl;
    return 0;
}

Second part: Reference

When you write code like int a = 3; int &b = a;, you intended to make b an alias for a which means "now a and b are same". Therefore int& products_id[] means a pointer to the reference of int. And I think that is not what you want.

tigertang
  • 445
  • 1
  • 6
  • 18
1

I shall start here at your first sentence:

I am trying to write a constructor for a class which contains an array as one of its attribute.

This is brave... Arrays are not first class elements of the language, and are often left hidden in standard containers. A general rule in C++ is: if you have no strong reason to use a raw array in C++, just stick to containers. Exceptions are:

  • interfacing with legacy or C code
  • implementation of custom containers
  • low level optimization
  • and of course learning...

Problems with arrays that are solved with containers:

  • the size of an array is determined at compilation time => use a std::vector here
  • you cannot directly assign arrays but only process them element wise => std::array is enough here
  • they silently decay to pointers when used in expressions, so when you pass an array to a function, the callee only receives a pointer to the first element and has no way to guess the size
  • dynamic raw arrays are hard to manage because the class will only contain a raw pointer, and you will have the ownership problem: one and only one free per malloc

So a class that contains an array as one of its attributes should not be an ordinary common class. It should either be a container with the copy/move/destructor problem (search for rule of 3, rule or 5). Or the size must be constant for coordinates for example.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • I am using this example to learn. Do you happen to know how to make the above code work? – Isfaaq Feb 18 '19 at 08:12
  • @Isfaaq: the other answer and yzt's comments explain that you have many problems here. And there is no way to have an **array** of unknow size in an object. It is not allowed by the language. So there are certainly way to meet the real underlying requirement, but I cannot just *make the above code work*. – Serge Ballesta Feb 18 '19 at 08:19
  • Thank you. I have edited the question. Maybe you can offer an alternative solution. – Isfaaq Feb 18 '19 at 12:17
  • 1
    @Isfaaq: Do not use arrays. Just have the sale class to contain a vector of items. I have said vector of items, not vector of pointers to items. And you can even emplace the items in the vector. – Serge Ballesta Feb 18 '19 at 12:34