My vector "myVec"

Would you, please, review my class myVec (to its point here), and tell my why I get the error:"type name is not allowed" for "throw invalid_argument;":

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include "std_lib_facilities.h"
#include <stdexcept>

using namespace std;

class myVec {

public:
    myVec(){} // Default constructor
    myVec(const int&); // Ordinary onstructor
    myVec(const myVec&);  // Copy constructor 
    myVec& operator=(const myVec&); // Copy assignment

    ~myVec() { delete [] elem; }  // Destructor - Release recources 

    const double& operator[](int i) const { return elem[i]; }
    double& operator[](int i) { return elem[i]; }

    const int size() const { return sz; }

private:
    double* elem = nullptr;
    int sz = 0;
};

//******************************************************
                               // Ordinary onstructor
myVec::myVec(const int& size) {
    elem = new double[size];
    sz = size;
}

//************************************************
                                        // Copy constructor 
myVec::myVec(const myVec& other) {
    if (other.elem != nullptr)
    {
        elem = new double[other.sz];  // Could throw "bad_allocate" but will be caught by try-catch

        for (int i = 0; i < other.sz; i++)
            elem[i] = other.elem[i];
        sz = other.sz;
    }

    else throw invalid_argument;
}

//**************************************************
                                          // Copy assignment
myVec& myVec::operator=(const myVec& other)
{
    if (this != &other)
    {
        if(other.elem == nullptr) 
            throw invalid_argument;
       
        double* p = new double[other.sz];  // Could throw "bad_allocate" but will be caught by try-catch

        for (int i = 0; i < other.sz; i++)
            p[i] = other.elem[i];

        delete[] elem; // Deleting old elements
        elem = p;
        sz = other.sz;
    }

    return *this;
}

//***********************************************
int main() try
{
    myVec v(5);
    cin.get();
    return 0;
}

catch (invalid_argument& e)
{
   cerr << e.what() << "\n";
   abort();
}
catch (bad_alloc& e)
{
    cerr << e.what() << "\n";
    abort();
}
catch (...)
{
    cerr << "Something went wrong\n";
    abort();
}




Last edited on
You need to throw an object. If you want to throw an object of type invalid_argument, then create an object of that type and throw it.

For example, invalid_argument("Beans"). This creates an object of type invalid_argument, with no name (it's a temporary) with the value "Beans" passed to the constructor.

Another example:
invalid_argument an_object("Bananas");
This creates an object of type invalid_argument, named an_object, with the value "Bananas" passed to the constructor.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <stdexcept>
#include <iostream>

using namespace std;

class myVec {

public:
    myVec(){} // Default constructor
    myVec(const int&); // Ordinary onstructor
    myVec(const myVec&);  // Copy constructor 
    myVec& operator=(const myVec&); // Copy assignment

    ~myVec() { delete [] elem; }  // Destructor - Release recources 

    const double& operator[](int i) const { return elem[i]; }
    double& operator[](int i) { return elem[i]; }

    const int size() const { return sz; }

private:
    double* elem = nullptr;
    int sz = 0;
};

//******************************************************
                               // Ordinary onstructor
myVec::myVec(const int& size) {
    elem = new double[size];
    sz = size;
}

//************************************************
                                        // Copy constructor 
myVec::myVec(const myVec& other) {
    if (other.elem != nullptr)
    {
        elem = new double[other.sz];  // Could throw "bad_allocate" but will be caught by try-catch

        for (int i = 0; i < other.sz; i++)
            elem[i] = other.elem[i];
        sz = other.sz;
    }

    else throw invalid_argument("Beans");
}

//**************************************************
                                          // Copy assignment
myVec& myVec::operator=(const myVec& other)
{
    if (this != &other)
    {
        if(other.elem == nullptr)
	  {
	    invalid_argument an_object("Bananas");
	    throw an_object;
	  }
       
        double* p = new double[other.sz];  // Could throw "bad_allocate" but will be caught by try-catch

        for (int i = 0; i < other.sz; i++)
            p[i] = other.elem[i];

        delete[] elem; // Deleting old elements
        elem = p;
        sz = other.sz;
    }

    return *this;
}

//***********************************************
int main() try
{
    myVec v(5);
    cin.get();
    return 0;
}

catch (invalid_argument& e)
{
   cerr << e.what() << "\n";
   abort();
}
catch (bad_alloc& e)
{
    cerr << e.what() << "\n";
    abort();
}
catch (...)
{
    cerr << "Something went wrong\n";
    abort();
}

Thank you for your reply.

with no name (it's a temporary)
1) Is it true for "any" class, please? I mean, does any expression with the type name plus a pair of parentheses with argument(s) for the class's constructor create a temporary object?

1
2
3
4
5
 if(other.elem == nullptr)
	  {
	    invalid_argument an_object("Bananas");
	    throw an_object;
	  }
2) Why have you used an object here, please? Just to show it's possible to create an object of the type and throw it?

1
2
3
4
5
catch (bad_alloc& e)
{
    cerr << e.what() << "\n";
    abort();
}
3) What string will be printed by this catch if a bad_alloc exception is thrown? Is there any default one?

Last edited on
1.) Yes. Assuming of course that the class is default constructable.
2.) You can only throw objects. You cannot throw types. The previous example can be rewritten as
 
throw invalid_argument("Bananas");

3.) It depends on the implementation.
TheToaster wrote:
1.) Yes. Assuming of course that the class is default constructable.

OP mentioned passing in any arguments required for a constructor, so the class wouldn't have to be default constructible.
Last edited on
Topic archived. No new replies allowed.