1. Trang chủ
  2. » Công Nghệ Thông Tin

Beginning Visual C plus plus phần 5 doc

123 277 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 123
Dung lượng 1,88 MB

Nội dung

CBox CBox::operator +(const CBox& aBox) const { // New object has larger length and width of the two, // and sum of the two heights return CBox(m_Length > aBox.m_Length ? m_Length : aBox.m_Length, m_Width > aBox.m_Width ? m_Width : aBox.m_Width, m_Height + aBox.m_Height); } You need to repeat this process for the operator*() and operator/() functions that you saw earlier. When you have completed this, the class definition in Box.h looks something like this: #pragma once class CBox { public: CBox(double lv = 1.0, double wv = 1.0, double hv = 1.0); ~CBox(void); private: // Length of a box in inches double m_Length; // Width of a box in inches double m_Width; // Height of a box in inches double m_Height; public: double GetHeight(void) const { return m_Height; } public: double GetWidth(void) const { return m_Width; } public: double GetLength(void) const { return m_Length; } public: double Volume(void) const { return m_Length*m_Width*m_Height; } 451 More on Classes 11_571974 ch08.qxp 1/20/06 11:21 PM Page 451 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com public: // Overloaded addition operator CBox operator+(const CBox& aBox) const; public: // Multiply a box by an integer CBox operator*(int n) const; public: // Divide one box into another int operator/(const CBox& aBox) const; }; You can edit or rearrange the code in any way that you want(as long as it’s still correct, of course. I have added a few empty lines to make the code a bit more readable. The contents of the Box.cpp file ultimately look something like this: #include “.\box.h” CBox::CBox(double lv, double wv, double hv) { lv = lv <= 0.0 ? 1.0 : lv; // Ensure positive wv = wv <= 0.0 ? 1.0 : wv; // dimensions for hv = hv <= 0.0 ? 1.0 : hv; // the object m_Length = lv>wv ? lv : wv; // Ensure that m_Width = wv<lv ? wv : lv; // length >= width m_Height = hv; } CBox::~CBox(void) { } // Overloaded addition operator CBox CBox::operator+(const CBox& aBox) const { // New object has larger length and width of the two, // and sum of the two heights return CBox(m_Length > aBox.m_Length ? m_Length : aBox.m_Length, m_Width > aBox.m_Width ? m_Width : aBox.m_Width, m_Height + aBox.m_Height); } // Multiply a box by an integer CBox CBox::operator*(int n) const { if(n%2) return CBox(m_Length, m_Width, n*m_Height); // n odd else return CBox(m_Length, 2.0*m_Width, (n/2)*m_Height); // n even 452 Chapter 8 11_571974 ch08.qxp 1/20/06 11:21 PM Page 452 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com } // Divide one box into another int CBox::operator/(const CBox& aBox) const { // Temporary for number in horizontal plane this way int tc1 = 0; // Temporary for number in a plane that way int tc2 = 0; tc1 = static_cast<int>((m_Length/aBox.m_Length))* static_cast<int>((m_Width/aBox.m_Width)); // to fit this way tc2 = static_cast<int>((m_Length/aBox.m_Width))* static_cast<int>((m_Width/aBox.m_Length)); // and that way //Return best fit return static_cast<int>((m_Height/aBox.m_Height))*(tc1>tc2 ? tc1 : tc2); } The shaded lines are those that you should have modified or added manually. The very short functions, particularly those that just return the value of a data member, have their defi- nitions within the class definition so that they are inline. If you take a look at Class View by clicking the tab and then click the + beside the CBox class name, you’ll see that all the members of the class are shown in the lower pane. This completes the CBox class, but you still need to define the global functions that implement operators to compare the volume of a CBox object with a numerical value. Adding Global Functions You need to create a .cpp file that will contain the definitions for the global functions supporting opera- tions on CBox objects. The file also needs to be part of the project. Click the Solution Explorer tab to display it (you currently will have the Class View tab displayed) and right-click the Source Files folder. Select Add > New Item from the context menu to display the dialog box. Choose the category as Code and the template as C++ File (.cpp) in the right pane of the dialog box and enter the file name as BoxOperators. You can now enter the following code in the Editor pane: // BoxOperators.cpp // CBox object operations that don’t need to access private members #include “Box.h” // Function for testing if a constant is > a CBox object bool operator>(const double& value, const CBox& aBox) { return value > aBox.Volume(); } // Function for testing if a constant is < CBox object bool operator<(const double& value, const CBox& aBox) { return value < aBox.Volume(); } // Function for testing if CBox object is > a constant 453 More on Classes 11_571974 ch08.qxp 1/20/06 11:21 PM Page 453 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com bool operator>(const CBox& aBox, const double& value) { return value < aBox; } // Function for testing if CBox object is < a constant bool operator<( const CBox& aBox, const double& value) { return value > aBox; } // Function for testing if a constant is >= a CBox object bool operator>=(const double& value, const CBox& aBox) { return value >= aBox.Volume(); } // Function for testing if a constant is <= CBox object bool operator<=(const double& value, const CBox& aBox) { return value <= aBox.Volume(); } // Function for testing if CBox object is >= a constant bool operator>=( const CBox& aBox, const double& value) { return value <= aBox; } // Function for testing if CBox object is <= a constant bool operator<=( const CBox& aBox, const double& value) { return value >= aBox; } // Function for testing if a constant is == CBox object bool operator==(const double& value, const CBox& aBox) { return value == aBox.Volume(); } // Function for testing if CBox object is == a constant bool operator==(const CBox& aBox, const double& value) { return value == aBox; } // CBox multiply operator n*aBox CBox operator*(int n, const CBox& aBox) { return aBox * n; } // Operator to return the free volume in a packed CBox double operator%( const CBox& aBox, const CBox& bBox) { return aBox.Volume() - (aBox / bBox) * bBox.Volume(); } You have a #include directive for Box.h because the functions refer to the CBox class. Save the file. When you have completed this, you can select the Class View tab. The Class View tab now includes a Global Functions and Variables folder that contain all the functions you just added. You have seen definitions for all these functions earlier in the chapter, so I won’t discuss their implemen- tations again. When you want to use any of these functions in another .cpp file, you’ll need to be sure that you declare all the functions that you use so the compiler will recognize them. You can achieve this by putting a set of declarations in a header file. Switch back to the Solution Explorer pane once more and right-click the Header Files folder name. Select Add > New Item from the context menu to display the dialog box, but this time select category as Code, the template asHeader File(.h), and enter the name as BoxOperators. After clicking the Add button an empty header file is added to the project, and you can add the following code in the Editor window: 454 Chapter 8 11_571974 ch08.qxp 1/20/06 11:21 PM Page 454 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com // BoxOperators.h - Declarations for global box operators #pragma once bool operator>(const double& value, const CBox& aBox); bool operator<(const double& value, const CBox& aBox); bool operator>(const CBox& aBox, const double& value); bool operator<(const CBox& aBox, const double& value); bool operator>=(const double& value, const CBox& aBox); bool operator<=(const double& value, const CBox& aBox); bool operator>=(const CBox& aBox, const double& value); bool operator<=(const CBox& aBox, const double& value); bool operator==(const double& value, const CBox& aBox); bool operator==(const CBox& aBox, const double& value); CBox operator*(int n, const CBox aBox); double operator%(const CBox& aBox, const CBox& bBox); The #pragma once directive ensures that the contents of the file are not included more than once in a build. You just need to add an #include directive for BoxOperators.h to any source file that makes use of any of these functions. You’re now ready to start applying these functions, along with the CBox class, to a specific problem in the world of boxes. Using Our CBox Class Suppose that you are packaging candies. The candies are on the big side, real jaw breakers, occupying an envelope 1.5 inches long by 1 inch wide by 1 inch high. You have access to a standard candy box that is 4.5 inches by 7 inches by 2 inches, and you want to know how many candies will fit in the box so that you can set the price. You also have a standard carton that is 2 feet 6 inches long, by 18 inches wide and 18 inches deep, and you want to know how many boxes of candy it can hold and how much space you’re wasting when it has been filled. In case the standard candy box isn’t a good solution, you would also like to know what custom candy box would be suitable. You know that you can get a good price on boxes with a length from 3 inches to 7 inches, a width from 3 inches to 5 inches and a height from 1 inch to 2.5 inches, where each dimension can vary in steps of half an inch. You also know that you need to have at least 30 candies in a box, because this is the minimum quantity consumed by your largest customers at a sitting. Also, the candy box should not have empty space, because the complaints from customers who think they are being cheated goes up. Further, ideally you want to pack the standard carton completely so the candies don’t rattle around. You don’t want to be too stringent about this otherwise packing could become difficult, so let’s say you have no wasted space if the free space in the packed carton is less than the volume of a sin- gle candy box. With the CBox class, the problem becomes almost trivial; the solution is represented by the following main() function. Add a new C++ source file, Ex8_08.cpp, to the project through the context menu you get when you right-click Source Files in the Solution Explorer pane, as you’ve done before. You can then type in the code shown here: 455 More on Classes 11_571974 ch08.qxp 1/20/06 11:21 PM Page 455 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com // Ex8_08.cpp // A sample packaging problem #include <iostream> #include “Box.h” #include “BoxOperators.h” using std::cout; using std::endl; int main() { CBox candy(1.5, 1.0, 1.0); // Candy definition CBox candyBox(7.0, 4.5, 2.0); // Candy box definition CBox carton(30.0, 18.0, 18.0); // Carton definition // Calculate candies per candy box int numCandies = candyBox/candy; // Calculate candy boxes per carton int numCboxes = carton/candyBox; // Calculate wasted carton space double space = carton%candyBox; cout << endl << “There are “ << numCandies << “ candies per candy box” << endl << “For the standard boxes there are “ << numCboxes << “ candy boxes per carton “ << endl << “with “ << space << “ cubic inches wasted.”; cout << endl << endl << “CUSTOM CANDY BOX ANALYSIS (No Waste)”; // Try the whole range of custom candy boxes for(double length = 3.0 ; length <= 7.5 ; length += 0.5) for(double width = 3.0 ; width <= 5.0 ; width += 0.5) for(double height = 1.0 ; height <= 2.5 ; height += 0.5) { // Create new box each cycle CBox tryBox(length, width, height); if(carton%tryBox < tryBox.Volume() && tryBox % candy == 0.0 && tryBox/candy >= 30) cout << endl << endl << “Trial Box L = “ << tryBox.GetLength() << “ W = “ << tryBox.GetWidth() << “ H = “ << tryBox.GetHeight() << endl << “Trial Box contains “ << tryBox / candy << “ candies” << “ and a carton contains “ << carton / tryBox << “ candy boxes.”; } cout << endl; return 0; } 456 Chapter 8 11_571974 ch08.qxp 1/20/06 11:21 PM Page 456 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Let’s first look at how the program is structured. You have divided it into a number of files, which is common when writing in C++. You will be able to see them if you look at the Solution Explorer tab, which looks as shown in Figure 8-13. Figure 8-13 The file Ex8_08.cpp contains the main()function and a #include directive for the file BoxOperators.h that contains the prototypes for the functions in BoxOperators.cpp (which aren’t class members). It also has an #include directive for the definition of the class CBox in Box.h. A C++ console program is usually divided into a number of files that will each fall into one of three basic categories: 1. .h files containing library #include commands, global constants and variables, class defini- tions and function prototypes— in other words, everything except executable code. They also contain inline function definitions. Where a program has several class definitions, they are often placed in separate .h files. 2. .cpp files containing the executable code for the program, plus #include commands for all the definitions required by the executable code. 3. Another .cpp file containing the function main(). The code in our main()function really doesn’t need a lot of explanation— it’s almost a direct expression of the definition of the problem in words, because the operators in the class interface perform problem- oriented actions on CBox objects. The solution to the question of the use of standard boxes is in the declaration statements, which also compute the answers we require as initializing values. You then output these values with some explana- tory comments. 457 More on Classes 11_571974 ch08.qxp 1/20/06 11:21 PM Page 457 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com The second part of the problem is solved using the three nested for loops iterating over the possible ranges of m_Length, m_Width and m_Height so that you evaluate all possible combinations. You could output them all as well, but because this would involve 200 combinations, of which you might only be interested in a few, you have an if statement that identifies the options that you’re actually interested in. The if expression is only true if there’s no space wasted in the carton and the current trial candy box has no wasted space and it contains at least 30 candies. Here’s the output from this program: There are 42 candies per candy box For the standard boxes there are 144 candy boxes per carton with 648 cubic inches wasted. CUSTOM CANDY BOX ANALYSIS (No Waste) Trial Box L = 5 W = 4.5 H = 2 Trial Box contains 30 candies and a carton contains 216 candy boxes. Trial Box L = 5 W = 4.5 H = 2 Trial Box contains 30 candies and a carton contains 216 candy boxes. Trial Box L = 6 W = 4.5 H = 2 Trial Box contains 36 candies and a carton contains 180 candy boxes. Trial Box L = 6 W = 5 H = 2 Trial Box contains 40 candies and a carton contains 162 candy boxes. Trial Box L = 7.5 W = 3 H = 2 Trial Box contains 30 candies and a carton contains 216 candy boxes. You have a duplicate solution due to the fact that, in the nested loop, you evaluate boxes that have a length of 5 and a width of 4.5, as well as boxes that have a length of 4.5 and a width of 5. Because the CBox class constructor ensures that the length is not less than the width, these two are identical. You could include some additional logic to avoid presenting duplicates, but it hardly seems worth the effort. You could treat it as a small exercise if you like. Organizing Your Program Code In this last example, you distributed the code among several files for the first time. Not only is this com- mon practice with C++ applications generally, but with Windows programming it is essential. The sheer volume of code involved in even the simplest program necessitates dividing it into workable chunks. As discussed in the previous section, there are basically two kinds of source code file in a C++ program, .h files and .cpp files. This is illustrated in Figure 8-14. There’s the executable code that corresponds to the definitions of the functions that make up the pro- gram. Also, there are definitions of various kinds that are necessary for the executable code to compile correctly. These are global constants and variables, data types that include classes, structures, and unions, and function prototypes. The executable source code is stored in files with the extension .cpp, and the definitions are stored in files with the extension .h. 458 Chapter 8 11_571974 ch08.qxp 1/20/06 11:21 PM Page 458 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Figure 8-14 From time to time, you might want to use code from existing files in a new project. In this case you only have to add the .cpp files to the project, which you can do by using the Project > Add Existing Item menu option, or by right-clicking either Source Files or Header Files in the Solution Explorer tab and selecting Add > Existing Item from the context menu to add the file to your pro- ject. You don’t need to add .h files to your project, although you can if you want them to be shown in the Solution Explorer pane immediately. The code from .h files is added at the beginning of the .cpp files that require them as a result of the #include directives that you specify. You need #include direc- tives for header files containing standard library functions and other standard definitions, as well as for your own header files. Visual C++ 2005 automatically keeps track of all these files, and enables you to view them in the Solution Explorer tab. As you saw in the last example, you can also view the class definitions and global constants and variables in the Class View tab. Function Definitions Function Definitions Function Definitions Definition of main() Source files with the extension .cpp Class Definition Class Definition Global Constants Global Constants Header files with the extension .h 459 More on Classes 11_571974 ch08.qxp 1/20/06 11:21 PM Page 459 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com In a Windows program, there are other kinds of definitions for the specification of things such as menus and toolbar buttons. These are stored in files with extensions like .rc and .ico. Just like .h files, these do not need to be explicitly added to a project because they are created and tracked automatically by Visual C++ 2005 when you need them. Naming Program Files As I have already said, for classes of any complexity, it’s usual to store the class definition in a .h file with a filename based on the class name, and to store the implementation of the function members of the class that are defined outside the class definition in a .cpp file with the same name. On this basis, the definition of our CBox class appeared in a file with the name Box.h. Similarly, the class implementation was stored in the file Box.cpp. We didn’t follow this convention in the earlier examples in the chapter because the examples were very short, and it was easier to reference the examples with names derived from the chapter number and the sequence number of the example within the chapter. With programs of any size though it becomes essential to structure the code in this way, so it would be a good idea to get into the habit of creating .h and .cpp files to hold your program code from now on. Segmenting a C++ program into .h and .cpp files is a very convenient approach, as it makes it easy for you to find the definition or implementation of any class, particularly if you’re working in a develop- ment environment that doesn’t have all the tools that Visual C++ provides. As long as you know the class name, you can go directly to the file you want. This isn’t a rigid rule, however. It’s sometimes use- ful to group the definitions of a set of closely related classes together in a single file and assemble their implementations similarly; however you choose to structure your files, the Class View still displays all the individual classes, as well as all the members of each class, as you can see in Figure 8-15. Figure 8-15 460 Chapter 8 11_571974 ch08.qxp 1/20/06 11:21 PM Page 460 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com [...]... CBox constructor called CCandyBox constructor1 called CBox constructor called CCandyBox constructor2 called myBox occupies 24 bytes myCandyBox occupies 32 bytes myMintBox occupies 32 bytes myMintBox volume is 6 The calls to the constructors are explained in the following table: Screen output Object being constructed CBox constructor called MyBox CBox constructor called MyCandyBox CCandyBox constructor1... called MyCandyBox CBox constructor called MyMintBox CCandyBox constructor2 called MyMintBox The first line of output is due to the CBox class constructor call, originating from the declaration of the CBox object, myBox The second line of output arises from the automatic call of the base class constructor caused by the declaration of the CCandyBox object myCandyBox Notice how the base class constructor... The CandyBox.h header file should contain: // CandyBox.h in Ex9_03 #pragma once #include #include “Box.h” using std::cout; using std::endl; class CCandyBox: public CBox { public: char* m_Contents; // Constructor to set dimensions and contents // with explicit call of CBox constructor CCandyBox(double lv, double wv, double hv, char* str = “Candy”) :CBox(lv, wv, hv) { cout . definition // Calculate candies per candy box int numCandies = candyBox/candy; // Calculate candy boxes per carton int numCboxes = carton/candyBox; // Calculate wasted carton space double space = carton%candyBox; cout. Objects are created by functions called constructors. The primary role of a constructor is to set values for the data members (fields) for a class object. ❑ C+ +/CLI classes can also have a static. 30 candies and a carton contains 216 candy boxes. Trial Box L = 5 W = 4 .5 H = 2 Trial Box contains 30 candies and a carton contains 216 candy boxes. Trial Box L = 6 W = 4 .5 H = 2 Trial Box contains

Ngày đăng: 12/08/2014, 10:21