Triangle ADT

Need high scores to pass this class.

The lab says: Notice that for this lab, there are no methods to modify a triangle's side-length data members once it has been constructed. The only way to establish a triangle with specific side lengths is to construct one.
However, it is possible to assign Triangle objects (e.g., TriA = TriB), while will create an exact copy. You can also create and assign a Triangle object "on the fly" (e.g., TriA = Triangle(3,4,5);).

triangle.h
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


class Triangle
{
public:
	// Constructor method prototypes
	Triangle();
	Triangle(const double side1, const double side2, const double side3);

	// Access method prototypes

	double getSideA() const;
	double getSideB() const;
	double getSideC() const;
	
	bool isRightTriangle() const;
	bool isEquilateralTriangle() const;
	bool isIsoscelesTriangle() const;
	double TriangleArea() const;
	
private:
	// assign the variables for the sides
	double side1, side2, side3;

	// check for a legal triangle
	bool isValid(double side1, double side2, double side3) const
	{
		return ((side1 < side2 + side3) && (side2 < side1 + side3) &&
			(side3 < side1 + side2) || (side1 == 0) || (side2 == 0) || (side3 == 0));
		 
	}
};


Triangle.cpp

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
96
97

#include "triangle.h"
#include <iostream>
using namespace std;

Triangle::Triangle()
	: side1(3), side2(4), side3(5)
{
	// side1 = 3;
	// side2 = 4;
	// side3  = 5;
}

Triangle::Triangle(const double side1, const double side2, const double side3)
{
	// check for a legal triangle

	if (!isValid(side1,side2,side3))
	{
		cout << "Invalid Triangle, setting defaults!" << endl;
		Triangle::side1 = 3;
		Triangle::side2 = 4;
		Triangle::side3 = 5;
	}
	// if not legal, assign the default values
	else
	{
	Triangle::side1 = side1;
	Triangle::side2 = side2;
	Triangle::side3 = side3;
	}

}


double Triangle::getSideA() const

{
	return side1;
}


double Triangle::getSideB() const

{
	return side2;
}

double Triangle::getSideC() const

{
	return side3;
}

// Check if the triangle is an Isosceles Traingle, ie, any two sides equal and different than the third.
bool Triangle::isEquilateralTriangle() const
{
	if (side1 == side2 && side2 == side3 && side1 == side3)
	{
		return true;
	}
	 return false;
	
}

//  Check if the triangle is Equilateral,ie, all sides are equal.
bool Triangle::isIsoscelesTriangle() const
{
	if (side1 == side2 || side2 == side3 || side1 == side3)
	{
		return true;
	}
	return false;
	
}

// Check if the triangle is a right triangle, ie, a triangle with a right angle.
bool Triangle::isRightTriangle() const
{
	if (pow(side3,2) == pow(side1,2) + pow(side2,2) || pow(side1,2) == pow(side3,2) + pow(side2,2) || pow(side2,2) == pow(side3,2) + pow(side1,2))

		return true;
	else
		return false;
	
}

// get the area of the triangle
double Triangle::TriangleArea() const
{
	float Area, s;
	s = (side1 + side2 + side3) / 2;
	Area = sqrt(s*(s - side1) * (s - side2) * (s - side3));
	return Area;
	
}


main.cpp

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
#include <iostream>
#include <string>

using namespace std;

#include "triangle.h"

// 
void printTriangleDetails(string label, const Triangle &tri)
{
	cout << label << " triangle: [";
	cout << tri.getSideA() << ", "
		<< tri.getSideB() << ", "
		<< tri.getSideC() << "]" << endl;

	if (tri.isRightTriangle())
		cout << "	Triangle is a right triangle" << endl;
	else
		cout << "	Triangle is not a right triangle" << endl;

	// etc, etc, etc, for the other details about a triangle object
	cout << endl;		// end of details for this triangle

}

int main()
{
	cout << "CSC2430 Triangle Lab:  Written by: My Name" << endl;
	Triangle t1;
	printTriangleDetails("Default", t1);
	
	Triangle t2(5, 4, 3);
	printTriangleDetails("t2(5,4,3)", t2);

	Triangle t3(4, 5, 3);
	printTriangleDetails("t3(4,5,3)", t3);

	Triangle t4(4, 6, 11);
	printTriangleDetails("t4(4,0,4)", t4);
	
	Triangle t5;

	t5 = t4;
	printTriangleDetails("Assigned t5=t4", t5);

	t5 = Triangle(3, 3, 3);
	printTriangleDetails("On-The-Fly assigned Triangle(3,3,3)", t5);

	if (t5.isIsoscelesTriangle())
	{
		cout << "Triangle is an Isosceles Triangle;" << endl;
	}
		return 0;

}
Last edited on
- be consistent whether you want your triangle sides to be called side1 or sideA
- bool isValid() doesn't need to be a member method:
C.4: Make a function a member only if it needs direct access to the representation of a class
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rc-struct

assign Triangle objects (e.g., TriA = TriB)

here you're looking for the copy assignment operator:
1
2
3
4
5
6
7
8
9
10
11
12
Triangle& Triangle::operator = (const Triangle& rhs)
{
    if(this == &rhs) //check if object assigned to itself
    {
        return *this;
    }
    side1 = rhs.side1;
    side2 = rhs.side2;
    side3 = rhs.side3;

    return *this;
}

create and assign a Triangle object "on the fly" (e.g., TriA = Triangle(3,4,5);).

and this is the copy constructor
1
2
3
4
5
6
Triangle::Triangle(const Triangle& rhs)
{
    side1 = rhs.side1;
    side2 = rhs.side2;
    side3 = rhs.side3;
}


Regarding the Triangle ctor:
1
2
3
4
5
6
Triangle::Triangle(const double side1, const double side2, const double side3)
{
	// check for a legal triangle
	//...
	// if not legal, assign the default values
}

this means that you're still left with a triangle object with default values so it might be preferable to delete this ctor overload and invoke the ctor's code through a separate method AFTER an isValid() check:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

struct Triangle
{
    double m_a;
    double m_b;
    double m_c;

    Triangle(const double& a, const double& b, const double& c) = delete;
};
int main()
{
    Triangle t(3,4,5);
}
//Error message: 
//error: use of deleted function 'Triangle::Triangle(const double&, const double&, const double&) 
Thank you for the thorough and concise feedback.

I don't believe our instructor wants us to use the * operator in this assignment.

I did go back and change the sides to be consistent using numbers and not letters.

Will also have not yet started using the this. method, although it would be useful, I don't think he is requiring for this assignment.

Will my program still accomplish the requirements? I ran a test, and it did copy the objects in main, when I specified t5 = t4.
I don't believe our instructor wants us to use the * operator ... not yet started using the this. method, ... I don't think he is requiring for this assignment. ... it did copy the objects in main, when I specified t5 = t4


how did you define the assignment operator overload without using this and/or * operator(s)?
Topic archived. No new replies allowed.