一个简单的证明

今天上概率课,有一个简单的问题,老师没有在课堂上证明,只是用venn diagram来说明。

P[(AB')∪(A'∩B)] == P(A) + P(B) - 2P(A∩B)

如图:所要求得概率就是两个圆扣除相交部分。

我的证明:

left hand = P(AB')+ P(A'∩B)             as (AB')and (A'∩B) are mutually exclusive events as (AB')belongs to A;

                                   (A'∩B)belongs to A', and A and A' are mutually exclusive events, so use Postulate3

= P(Ф∪(AB'))+ P(Ф∪(A'B))                       Identity Law

= P((A∩A')∪(AB'))+ P((B∩B')∪(A'B))              Negation Law

= P(A(A'B')) + P((B(A'B'))                     Distributive Law

= P(A(AB)') + P(B(AB)')                       De Morgan's Law

= 1 - P((A(AB)')') + 1- P((B(AB)')')          Theorem 2.3

= 1 - P(A'(AB)) + 1 - P(B'(AB))              De Morgan's Law

= 1 - (P(A') + P(AB) - P(A'(AB))) + 1 -(P(B') + P(AB) - P(B'(AB)))  Theorem 2.7

= (1- P(A')) + (1 - P(B')) - 2P(AB) + P(ФB) + P(ФA)       Associative Law & Negation Law

= P(A) + P(B) - 2P(AB) + 2P(Ф)                       Theorem 2.3 and Domination Law

= P(A) + P(B) - 2P(AB) = right hand                Theorem 2.4

proved!

 C++的小错误

To: Professor Ms. Leila Kosseim

Dear Madam Kosseim,

I am your student in course COMP248 and I found out there is a  small mistake in your class.

In class you use 

    cout<<setf(ios::showpoint);

    cout<<setf(ios::fixed);

    cout<<precision(2);

In fact, it is wrong, you should use cout's member function setf(), instead of operator "<<" as followoing:

    cout.setf(ios::showpoint);

    cout.setf(ios::fixed);

    cout.precision(2);

or if you really prefer to using the parameterized manipulator, you have to include "iomanip" and like this:

    cout<<setiosflags(ios::showpoint|ios::fixed);

    cout<<setprecision(3);

 

Thank you for your time in advance.

 

B.Rgds

 

Qingzhe Huang

 

Here is the reply from Madam:

yes.  I verified it and you are right. I mixed up setf and setiosflags. I will correct the mistake in class Friday.

thanks for telling me.

LK

Is it still correct for your suggested expression of theorem?

 

Hi Doctor,

In today's class you clarified some points about "logically equivalence", and I checked with my notes and found out that in previous class you gave an expression of theorem as following:

(pq) (p←→q T)

However, you erased it later and said it was not correct. After your clarification about "equivalence", I wonder if it IS INDEED CORRECT after all. The following is the truth table I made, I am not sure if it is right or not. Can you check it? 

p       q           pq    p←→q      p←→qT

T    T      T         T            T

T    F      F         F            F

F    T      F         F            F

F    F      T         T            T

 

As "T" is itself a proposition with truth value that is always true, right? Therefore according to definition of "equivalence" that only when the two proposition "p←→q" and "T" have the same truth value, they are equivalence. So, only when proposition "p←→q" is true, compound proposition (p←→q T) has true value or in other words that it is true that p←→q is equivalent to proposition TRUE. So, we observe that proposition (pq) has same truth table as proposition (p←→q T). Then they are logically equivalent or (pq) (p←→q T) is true.

Is above correct?

Thank you for your time and patience.

B.Rgds,

Qingzhe Huang

             A small doubt about 2's complement...

Dear Professor Hina,

I am a student in your section NN and I have a small question about 2's complement.

After 2's complement, a negative number will be tranformed into its positive counter-part, so does the positive. But how about the lowest negative one?

For example of 4bit, the lowest negative is 1000 which is equal to -8. However, after 2's complement, it becomes 1000 again! Does it suggest that the lowest negative one is an exception of 2's complement rule? Or when we encounter the lowest of negative number and want to find out its positive counterpart, how should we do?

 

Thank you for your time,

QingZhe Huang

        My assignment here...

//****************************************************//
// First Assignment for Comp248						  //	
// Program Title: Ice Cream Experiment				  //	
// Author: Qingzhe Huang							  //
// Section: X                                         //
// Student ID: 5037735                                //
//****************************************************//
#include <iostream>
using namespace std;
const double SweetPerLiter = 0.35;  //sweetner weight per liter of ice cream
void display(double, double, double);
int main()
{
	double mouse, dieter, lethal;
	char choice[10];  //to store user's input choice to decide if repeat inputting
	//set up a menu to ask user if repeat input is desired
	cout<<"\nInput or Quit?(quit)\n";
	cin>>choice;
	while (strcmp(choice, "quit")!=0)//use 'quit' to determine if quit
	{
		cout<<"\nEnter the weight of the mouse in grams: ";
		cin>>mouse;
		cout<<"\nEnter the lethal dose for the mouse in grams: ";
		cin>>lethal;
		cout<<"\nEnter the desired weight of the dieter, in Kilograms: ";
		cin>>dieter;
		//a display subroutine to make easy reading
		display(mouse, lethal, dieter);
		//ask user if repeat input is desired
		cout<<"\nInput or Quit?(quit)\n";
		cin>>choice;
	}
	return 0;
}
//a routine for display of result with 3 parameters of input data
void display(double mouse, double lethal, double dieter)
{
	double temp;  //temperarily store the lethal dose in order to calculate icecream liter
	long preFlag; //previous display format should be saved and restored after display
	temp = dieter / mouse * lethal;  //the lethal weight for dieter
	cout<<"\nFor these parameters:\n";
	cout<<"\tmouse weight: "<<mouse<<" grams\n";
	cout<<"\tlethal dose for the mouse: "<<lethal<<" grams\n";
	cout<<"\tdesired dieter weight: "<<dieter<<" kilograms\n";
	//set up display format to make precision of 3 and fixed format;
	preFlag = cout.setf(ios::fixed);
	prePrec = cout.precision(3);
	cout<<"The lethal dose for sweetener is "<<temp<<"kilograms\n";
	cout<<"The leathal quantity of ice cream is "<< temp* SweetPerLiter<<" kiloliters\n";
	//restore previous display format flag and precision
	cout.flags(preFlag);
}


  Here it is asked...

Hi Sir,
 
I am student from your class of COEN244.
Just to clear the little doubt of declaration of pointer in your class, see following is from your slides:
 
int number=10, int* pNumber = &number;
 
Actually the second "int" after comma is unneccessary, after compilation the warning of VC++
"warning C4518: 'int ' : storage-class or type specifier(s) unexpected here; ignored"
 
and it is perfect clear to declare as following:
 
int number=10, * pNumber = &number;
 
The compiler satisfies with this declaration and no need to repeat "int" after comma. Similar cases are all over your slides:
 
Time t, * pT = &t;
 
Sorry for my fussy on details as I am Computer Science student with "Software System" option and I treat this course very seriously. I feel a bit sad that most students in class are from "Hardware" options which probably means that programming is only an option for them. The unexpected "EARLY" termination of first lecture worries me a lot. I do hope you understand that very few software-optioned students do treat your lectures very seriously.
 
Here is my answer to your question in class: "What do you expect to get after this course?"
I run into many doubts and confusions in programming from time to time, and it is expected that this course can systematically show me the answer.
 
Thank you for your patience in advance,
 
Qingzhe Huang/Nick Huang

    Here it is answered...

Hi,

> I am student from your class of COEN244.
> Just to clear the little doubt of declaration of pointer in your class,
> see following is from your slides:
>
> int number=10, int* pNumber = &number;
>
> Actually the second "int" after comma is unneccessary, after
> compilation the warning of VC++
> "warning C4518: 'int ' : storage-class or type specifier(s) unexpected
> here; ignored"
>


Thank you for the clarification.  I will correct myself next class.


> Sorry for my fussy on details as I am Computer Science student with
> "Software System" option and I treat this course very seriously. I feel
> a bit sad that most students in class are from "Hardware" options which
> probably means that programming is only an option for them.


Actually, in engineering it is a mandatory course.  The way I teach this
course will not differ due the students background.  They will have to
learn how program using OO methodology.


> The unexpected "EARLY" termination of first lecture worries me a lot. I do
> hope you understand that very few software-optioned students do treat
> your lectures very seriously.


Don't worry about the "EARLY" termination.  I had that planned before I
got in there... I have to "EASE" people (including myself) into a summer
course :)


> Here is my answer to your question in class: "What do you expect to get
> after this course?"
> I run into many doubts and confusions in programming from time to time,
> and it is expected that this course can systematically show me the
> answer.

That is exactly my plan!  My lectures are to guide and inspire you
to practice programming.  Learning to program well is really up to the
individual.  But we will look into some "systematic" ways to solve
programming problems.

Regards,
Chris
 

  Here it is asked...

On Tue, 8 Jul 2003, Hotmail wrote:

> Hi sir,
>
> Thank you so much for your reply.
> As I was doing assignment 1, once again I spent a fruitless afternoon to
> solve my old, long-term painful problem:
>
> I was supposed to ask user to input a number (int , float or whatever). The
> usual way is to use cin>>aVariable;
> But suppose the naughty user key in a character, say 'q' or whatever. The
> program crash.
>  I searched MSDN for ways to "peek" the character before assign value to the
> "aVariable". However, there is no way to "assign" value. I AM able to check
> character by character by using cin.get() or peek(). But it seems that I
> need to re-implement "char"-to-"int" or "char"-to-"float" which I don't want
> to.
>
> I run into this problem from time to time, and cannot find a proper way to
> handle. Can you give me some suggestion?
>
> Thank you for your patience,
>
> B.Regards,
>
> Nick Huang
 

    Here it is answered...

Ok!  I've come up with this solution:

================================================================
#include <iostream>

using std::cin ;
using std::cout ;
using std::endl ;

void main() {

int variable ;

cin >> variable ;

// Check the failbit error flag
if ( ! cin.fail() )
cout << "This is the integer " << variable << endl ;
else {
cout << "This is NOT an integer!" << endl ;
// Clear error flags
cin.clear() ;
// Empty input buffer
cin.get() ;
}
}
========================================================================

Hope this helps!

Best Regards,
Chris Taillefer
 

     here goes the unexpected result...

hi sir,
 
As for  the question of "new" with 0 size of array, it will not return a NULL pointer.
 
int main()
{
 int * pInt = new int[0];
 if (pInt==NULL)
 {
      cout<<"Null!"; //this will never be executed!
 }
 return 0;
}
 
"pInt" will not be NULL and I don't know why.  Just let you know as you requested.
 
Have a nice day,
 
Nick Huang/qingzhe huang
 

           Can you tell who is who?

Hi sir,
 
Maybe I didn't express myself clearly in class because I asked you the question that is it possible for "friend" function to access member functions of class?
Because when you mentioned that a friend function to a class is accessable to the private MEMBERS of the class, I arbitarily regarded MEMBER FUNCTIONS are also
part of MEMBERS. And your answer is positive, if my memory is correct, though I am not sure.
So, can you confirm me about this issue? Because the error message of compiler shows that there is no way to access PRIVATE MEMBER FUNCTIONS OF A CLASS BY FRIEND FUNCTIONS.
 
Also an idea came to my mind and I can not help to say that the overloading of operator may lead to ambiguity. See code following:
I overload operator << both in member function of class MyClass and in friend function.  The format of operator is similar:  MyClass&<< int.
 
And compilation is OK, but when executing, compiler is unable to recognize which function is invoked.  The error message is "error C2593: 'operator <<'

 is ambiguous".

 
So, it seems to me that friend function may act as same as member functions by overloading operators, right? (suppose there is no member function<<,

can you recognize it is friend function or member functions?)

 
Awaiting your comment,
 
have a nice day,
 
Nick Huang/Qingzhe Huang
 

 

class MyClass
{
	friend MyClass& operator<<(MyClass& , int );
public:
	MyClass& operator<<(int);
};

int main()
{
	MyClass M;
	M<<45;
	return 0;
}

MyClass& operator<<(MyClass& dummy, int number)
{
	cout<<"this is friend!";
	return dummy;
}

MyClass& MyClass::operator <<(int number)
{
	cout<<"this is members";
	return *this;
}
	The explanation...
This code is ambiguous because when you call the function similar to

MyClass aClass ;
aClass << 5 ;

the operator<< function that is call must have the "signature" of a
MyClass object on the LHS and an int on the RHS.  Both function have the
same signature.  So the compiler does not know which one to use.
 
	So private member function is indeed accessible
> Hi sir,
>
> Maybe I didn't express myself clearly in class because I asked you the question that is it possible for "friend" function to access member functions of class?
> Because when you mentioned that a friend function to a class is accessable to the private MEMBERS of the class, I arbitarily regarded MEMBER FUNCTIONS are also
> part of MEMBERS. And your answer is positive, if my memory is correct, though I am not sure.
> So, can you confirm me about this issue? Because the error message of compiler shows that there is no way to access PRIVATE MEMBER FUNCTIONS OF A CLASS BY FRIEND FUNCTIONS.
>

Private member functions and data are accessable to friend functions.  You
must have done something else wrong.  Here is a peice of code I used to
test your claim...


class Test {
        friend void foo(Test&) ;
private:
        char* foobar() { return "This is a test!"  ; }
} ;

void foo(Test& tmp) {
        cout << tmp.foobar() ;
}

void main() {

        Test object ;
        foo( object ) ;

}
 

warning C4172: returning address of local variable or temporary

hi sir,
 
As for the question of memory leaking, I asked you the possible solution and you suggested that a reference of local variable should be returned. But it seems not workable. See the piece of code following:
 
1. I use a static int counter to count the number of objects.
2. The private data index record the index of object.
3. Function foo() return the reference of a local object. //This is warned by compiler: warning C4172: returning address of local variable or temporary
4. A constructor assigns index with counter and increment counter.
5. print() just print the data.
 
The result of running of program is like this:
 
object of 1
object of 2
the index of object is-858993460
Press any key to continue
 
 
 
class Test
{
 static int counter;
 int index;
public:
 Test& foo();
 Test();
 void print();
};
 
int Test::counter = 0;
 
int main()
{
 Test t1;
 t1.foo().print();
 
 return 0;
}
 
//constructor assign member index and increment counter
Test::Test()
{
 cout<<"object of "<<++counter<<endl;
 index = counter; 
}
 
//print index.
void Test::print()
{
 cout<<"the index of object is"<<index<<endl;
}
 
//return a reference to local variable
Test& Test::foo()
{
 Test Result;
 return Result;
}
 
 
The conclusion:
1. We cannot gurantee the member data if return type is reference of a local variable.
2. As long as no member data is touched, the return of reference of local variable is OK. For example, suppose the print() function doesnot print any member  data, like
    cout<<"no member data is touched"; , then everything seems OK. Because a method of a class is always same, even reference to  the object is invalid. I guess only the type of object matters when invoking member functions of an object.
3. If the function foo() returns a value instead of reference, everything is OK.
 
I hope you can justify these above, thank you for your time.
 
B.regards,
 
 
Nick Huang

More about returning a reference to a local variable...

Hi Sir,
 
1.   Regarding to the question of returning a reference of a local variable, have you checked my previous email which titled "warning C4172: returning address of local variable or temporary". In the mail, I showed you an example program to prove that returning of reference to a local variable will not give correct result.
 
2.  Here I made another example to show the problem:
Here is the running result:
 
Number is 4200098
Press any key to continue
 
Here is the code:
 
 
class Local
{
private:
 int index;
public:
 Local(int number =5);
 void display(){ cout<<"Number is "<<index<<endl;}
};
 

Local& copyLocal();
 
int main()
{
 Local l1, l2(10);
 
 //here memberwise copy is not really necessary
 //I even tried a more simple way: copyLocal().display();
 //which shows the DIFFERENT garbage data
 l1 = copyLocal();
 l1.display();
 
// copyLocal().display();
 
 return 0;
}
 
//a simple function return referece of a local variable
Local& copyLocal()
{
 Local l(15);
 return l;
}
 
//a simple constructor with default input of 5
Local::Local(int number)
{
 index = number;
}
 
 
3.   However, your example showed in lecture DID WORK!
 
See a piece of code similar to your example given in class:
 
int& localRef(int x);
 
int main()
{
 int x =10;
 cout<<"the number should be 40: "<<localRef(x)<<endl;
 
 return 0;
}
 
int& localRef(int x)
{
 int result = x*4;
 return result;
}
 
 
The result is what you described in class:
 
the number should be 40: 40
Press any key to continue
 
4.  I really don't know why!!? Why the return of simple data type like int will give correct result and for structure, it is not! My wild guess is that the local variable is usually stored in stack, (I once read this in a book of MASM--assembly language). The returning of such a reference is not reliable, since there is a greater chance that a bigger data structure might be destroyed by the stack after the function call than a simple basic data type variable like int, right?  This is simply my wild guess.
 
5. Awaiting your comment.
 
B.Rgds,
 
Nick Huang/Qingzhe Huang

Here comes the reply...

Hi Nick.  You were right about your previous example, but only on windows.
I compiled on Unix and it gave me a warning but still worked anyway.

I believe that this particular mechanism is operating system dependent.
Hence it is not good way to program.  I will give more in class on Monday.

Best Regards,
Chris Taillefer
P/T Faculty
 

 

Your tutorial is great! And I just want to say thank you for your great job!

Hi,
 
Do you remember that I mentioned the problem that global variable defined in header file cannot pass compilation? See the following two .cpp file and one .h file
 
multi.h
 
#ifndef multifile_h
#define multifile_h
 
#include <iostream>
 
int myInt =9;

void test();
#endif
 
 
main.cpp
 
#include "multifile.h"
#include <iostream>
 
using namespace std;
 
int main()
{
 myInt = 10;
 test();
 return 0;
}
 
 
multi.cpp
 
#include "Multifile.h"
 
using namespace std;
 
void test()
{
 cout<<"my int is "<<myInt;
}
 
 
 
1. The global variable myInt is used by both multi.cpp and main.cpp, but the compiler simply give you an error that this global variable "myInt" is defined more than once. This is really crazy! Why cannot we use it?
2. I tried to compile it in command line, it remains the same. I guess it is due to the linker who encounter same symbol in two .obj---main.obj and multi.obj, so it THINKS this variable is defined more than twice.
3. I search in MSDN, and find out the switch "/FORCE:MULTIPLE" which ignores the multi-definition. Then I compile it with this switch in command line, it gives warning, but it works and output is correct. So it is solved.
4. Just want to share this with you, and please send me the example of "Double Pointer", thank you for that.
5. Your tutorial is great! And I just want to say thank you for your great job!
 
have a nice day,
 
Nick Huang
		A little tip about "conversion constructor"
We all know that C++ will automatically try to convert a function call with closest argument, for example, when we overloaded
the operator= of member function of class String. When we call String = "a char string"; compiler will try to convert "a char 
string" into an object of String, see below:
#include <iostream>

using namespace std;

class String
{
private:
	char* sPtr;
	int length;
public:
	String(const char * =" " );
	char* getStr() const;
	~String();
	const String & operator=(const String&);
	void print(){cout<<sPtr<<endl;}
};

int main()
{
	String S("string S");
	S.print();
	S = "change to this!";
	S.print();
	return 0;
}

char* String::getStr() const
{
	 return sPtr;
}


const String& String::operator =(const String& right)
{
	delete [] sPtr;
	length = strlen(right.getStr());
	sPtr = new char[length+1];
	strcpy(sPtr, right.getStr());
	return *this;
}



String::~String()
{
	delete []sPtr;
	length = -1;
}

String::String(const char* str)
{
	length= strlen(str);
	sPtr = new char[length+1];
	strcpy(sPtr, str);
}
The result is like following:
string S
change to this!
Press any key to continue
But keep in mind that it will not always succeed in conversion unless you define your overloaded function properly. That is
it works only if you define the parameter of operator = as const. Otherwise it won't work.

 

for composition object, initialization is only optional!

 
Hi Sir,
 
1. Regarding the first part of question NO. 4 in mid term, your solution is to initialize the private String object msg in constructor. But I think since this is the case of composition not inheritance, the initialization is only optional.
 
2.  See your lecture slides in class2 of compostion example, the Date class has a composition object Time class time, in the constructor, you simply call the object time.setTime(sec, min, hour);
 
3. Therefore, I think my solution for the midterm should be regarded as correct in this case:
 
Message::Message(const char* data)
{
    msg = data;
}
 
Here I call the String class overloaded operator= and implicitly call converstion constructor to convert char* into object String, then assign data to msg. Right? Of course I understand this is not efficient since msg object is first initialized with empty string then assigned by operator=.  However, it is at least a correct method, right?
 
 
4.  The following is just a simple demo I wrote to test my solution of midterm. To simplify situations, I omit all other function except operator=, and to get around the private data sPtr, I invented a method getStr() to access the char* pointer.
 
5.  The result of program is what I expected---it print out the message correctly as following:
This is a message!Press any key to continue
 
6. 
class String
{
private:
 char* sPtr;
 int length;
public:
 char* getStr()const {return sPtr;}
 String(const char* =" " );
 
// String(const String&);
// ~String();
 const String & operator=(const String&);
// const String& operator+=(const String&);
// String operator()(int start, int length);
};
 
class Message
{
private:
 String msg;
public:
 Message(const char* =" " );
 void print(){cout<<msg.getStr();}
// Message(const Message&);
// bool operator==(const Message& right);
};
 
int main()
{
 Message M("This is a message!");
 M.print();
 
 return 0;
}
 
Message::Message(const char* str)
{
 msg = str;
}
 

String::String(const char* str)
{
 length= strlen(str);
 sPtr = new char[length+1];
 strcpy(sPtr, str);
}
 
const String& String::operator =(const String& right)
{
 delete[]sPtr;
 char* ptr = right.getStr();
 length = strlen(ptr);
 sPtr = new char[length+1];
 strcpy(sPtr, ptr);
 return *this;
}
 
 
Thank you for your time and have a nice day,
 
 
Nick Huang/Qingzhe Huang
Can you confirm this?
> > 2.  See your lecture slides in class2(COEN244Class2.pdf) of compostion
> > example, the Date class has a composition object Time class time, in the
> > constructor, you simply call the object time.setTime(sec, min, hour);
>
> This is a set method, NOT A CONSTRUCTOR CALL. There were no set methods
> provided to you in the prototype!

Even there is no set method provided in prototype, an overloaded assign
operator = is provided in prototype. So, it can be regarded as an set method
plus we use conversion constructor:

msg = data;   //operator= is used and data is converted to be temperary
object by conversion constructor

Of course, as I said in my mai, this is not efficient way since object msg
is initialized first to be empty string, then assigned secondly. But I think
it works. Can you confirm this?

Thank you for your time,

Nick Huang/Qingzhe Huang
it would work, albeit inefficient!
Hi Nick, it would work, albeit inefficient!

Chris
Is conversion constructor involved here? I doubt it...
Hi,

1.  As promised in tutorial, I tried to test to see if conversion constructor is playing any role in following:

class Shape
{
protected:
 double data;
public:
 Shape(double d=1):data(d){cout<<"shape constructor\n";}
};


class Square: public Shape
{
private:
 double side;
public:
 Square(double side=3):side(side), Shape(side){cout<<"square constructor\n";}
};

int main()
{
 Shape aShape;
 aShape =Square(7);

 return 0;
}

2.  The running result is like following:
shape constructor
shape constructor
square constructor
Press any key to continue

3. The first line obviously belongs to aShape construction, and 2nd, 3rd line is due to Square(7). But I am still not sure about whether conversion constructor is involved here. So, I change the main function a little bit:

int main()
{
 Shape aShape;
 aShape =7;

 return 0;
}

4. The new running result is like following: and it is a REAL CONVERSION CONSTRUCTOR HERE. 

shape constructor
shape constructor
Press any key to continue

5. So, it seems to me that the code "aShape =Square(7);" is only doing member-wise copy and no conversion constructor is playing any role here. Though I am not quite sure about this, what do you think?

Thank you for your time,

Nick Huang/Qingzhe Huang
		Do we lose the file pointer?
As simple as following code, what would you expect? Does file "test2.txt" was created? And what is written in file "test1.txt"?
The answer is that "test2.txt" was not created and nothing was written into "test1.txt". Do you believe?
	int main()
	{
		ofstream f;
		f.open("test1.txt");
	
		f.open("test2.txt");
		f<<5;
		return 0;
	}
	My question for final
#include <iostream>

using namespace std;

template<class T, class X>
class Base
{
public:
		virtual X pubTest(T t);
};

template<class X, class T>
class Derived: public Base<T, X>
{
public:
		virtual X pubTest(T t);
};

int main()
{
	Base<int, char> *pB = new Derived<char, int>;
	try
	{
		pB->pubTest('A');
	}
	catch(int i)
	{
		cout<<"catch int "<<i<<endl;
	}
	catch(char c)
	{
		cout<<"catch char "<<c<<endl;
	}
	return 0;
}

template<class T, class X>
X Base<T, X>::pubTest(T t)
{
	throw t;
	return t;
}

template<class X, class T>
X Derived<X, T>::pubTest(T t)
{
	X x = 'A';
	try
	{
		Base<T, X>::pubTest('A');
	}
	catch(T)
	{
		throw x;
	}
	catch(X)
	{
		throw t;
	}
	return x;
}
A const demo
#include <iostream>

using namespace std;

class Demo
{
private:
	int data;
	//the "ptr" pointing to "data"
	int* ptr;

	//const data member is nothing but const values, so, they must be 
	//initialized by initializer BEFORE constructor
	const int constData;

public:
	//even reference is given you still cannot change "data"
	const int& constValueRef(){ return data;} 
	//you have the pointer by its reference, and similarly you cannot change data,
	//but you can change the pointer---"ptr"
	const int*& constValuePtr() { return ptr;}
	//the pointer itselft---ptr--cannot be changed, but the data
	//which pointed to can be changed. In this case, you can change "data"
	//but not "ptr"
	int*  const& constPtr() { return ptr;}

	//even you have the access to constant data by reference, you
	//still cannot change it. What's more, compiler force you to declare 
	//return value as "const int"
	const int& getConstData(){	return constData;}

	//a const member function only for const object to be called
	int getData() const { cout<<"this is const function, should be called by a const"
		<<" object"<<endl; return data;} 

	//it is an overloading to the const version of "getData"
	int getData(){cout<<"this is not const version, so, when const object call"
		<<"getData(), it won't be called\n"; return data;}

	//you cannot overload a function only by different type of "return value"
//	const int getData() {return data;} //error, cannot overload

	void test();

	Demo();

};

//a test function with const object as parameter
void testConst(const Demo& D);

//a wild test 
void testWild(Demo& D);


int global = 100;

int main()
{
	Demo D;
	D.test();
	testConst(D);
	testWild(D);
	return 0;
}

//const data should be initialized before constructor
Demo::Demo() : constData(global)
{
	data = 10;
	ptr = &data;
}

void Demo::test()
{
//	constValueRef() = 12; //Error, try to modify const value
//	*(constValuePtr()) = 13;// Error,try to modify const value
	constValuePtr() = &global; //OK, only change pointer, not data;
//	constPtr() = &global; //Error, try to modify pointer
	*constPtr() = global; //OK, only change the data

//	getConstData() = 11;//Error, you cannot change a const

}


void testConst(const Demo& D)
{
	//can you guess which version of getData() is called here?
	D.getData();
	//obviously, the const version is called, even you don't specify which one.
}

void testWild(Demo& D)
{
	//can you guess which version of getData() is called here?
	D.getData();
	//originally I expect the sequence of function declared may have effect.
	//but it turned out that non-const object call non-const member functions.

	//if you do want to call the const version of "getData()":
	//then change the object to be type of "const object"
	((const Demo)(D)).getData();
	
}
 

Re: I am not asking for something,

but I do want to make it clear that I finished assignment 6 early last week...

 
Hi Sir,
 
I came directly from a hard work, so I was late for the lecture and forgot to bring my assignment 6. I understand it is impossible for you to accept unprinted one. However, I want to make it clear that I finished it early last week. Enclosed copy might show that and hopefully my mark of final might prove that I am telling the truth.
 
I implement a template function of "generalTest()" in driver program so that we can test both "int" and "char*" with this same function by passing their type as parameter. I hope this is what you expect us to understand about the purpose of template which save us the "copy&paste" job. 
 
//this template function can test all data type provided
//user pass a data array with same data type of the array class
template<class T>
void generalTest(Array<T>& A, T* dataArray);
 
Thank you for your time and best regards,
 
 
Nick Huang/Qingzhe Huang
The friend function of a template class can only be defined in formate of inline function, right?
This is really ridiculous! I understand that there might be some difficulty in designing compiler, but there should be some ways!
	Is it a bug with VC++???
See following, it is as simple as an overloading of operator by friend function of a simple class. But compiler continually gives
a strange error: 
fatal error C1001: INTERNAL COMPILER ERROR
(compiler file 'msc1.cpp', line 1786) 
I tried all my way and cannot solve it. It seems a strange error with friend function, since when I changed the friend function 
with no operator overloading, there is no error again. 
#include <iostream>

using namespace std;

class  MyClass
{
	friend int operator +(int i, const MyClass& M);
private:
	int data;
public:
};


int main()
{
	return 0;
}

int operator +(int i, const MyClass& M)
{
	return i+M.data;
}
 
No operator overload:
class  MyClass
{
	friend int add(int i, const MyClass& M);
private:
	int data;
public:
	MyClass(int i=10): data(i) {;}
};


int main()
{
	MyClass M;
	cout<<add(5, M);
	return 0;
}

int add(int i, const MyClass& M)
{
	return i+M.data;
}
 
I think there must be some mistakes in question 8...
Hi Professor,
 
Regarding the assignment 1, I think there are quite a few mistakes.
1.  Taking question 8 as an example, the integrate formular is obviously incorrect. As the correct one should be 1/2[f(a)+f(b)]*(b-a), instead of 1/2[f(a)+f(b)]/(b-a).  Because the dividing makes really no senses, right?
 
2. Secondly "trapezoidal rule" works well if the function f in  interval [a,b] is linear. This implies that we should compare the "SLOPE" of  two half interval  of functions, that is,  if [f(b) - f(m)]/(m-a) is close to [f(b) - f(m)]/(b-m), is it right?
 
So, my solution is like following:
 
--this trape function is the integrate formular, corrected from "divide" to "multiply"
trape f a b = (f a + f b)*(b-a)*0.5
 
--this slope function calculate the function f's "slope" at interval [a,b]
slope f a b = (f b - f a)/(b-a)
 
 
--if the slope of two interval is close within a tolerance e=0.001, we return one of the integrate formular, of course it should
--multiply by 2. If not, recursively call integrate function again.
 
integrate f a b =  if abs (slope f a (half a b) - slope f (half a b) b) <e
   then (trape f a (half a b))*2
   else integrate f a (half a b) + integrate f (half a b) b  where e =0.001
 
--the result is like following which is quite close to your test:
 
A1> integrate sin 0 pi
2.0
 
I hope you can confirm above. thank you for your time.
 
Nick Huang/Qingzhe Huang

                Why don't I check website first?

> Regarding the assignment 1, I think there are quite a few mistakes.

I announced the mistakes in class and put a corrected version of the 
assignment on the course website.

> 1.  Taking question 8 as an example, the integrate formular is obviously 
> incorrect. As the correct one should be 1/2[f(a)+f(b)]*(b-a), instead of 
> 1/2[f(a)+f(b)]/(b-a).  Because the dividing makes really no senses, right?

Yes.

> 2. Secondly "trapezoidal rule" works well if the function f in  interval 
> [a,b] is linear. This implies that we should compare the "SLOPE" of  two 
> half interval  of functions, that is,  if [f(b) - f(m)]/(m-a) is close 
> to [f(b) - f(m)]/(b-m), is it right?

The trapezoidal rule assumes that the function is linear.  However, 
computing the slope is not a good way of finding out whether it is accurate.

> So, my solution is like following:
>  
> --this trape function is the integrate formular, corrected from "divide" 
> to "multiply"
> trape f a b = (f a + f b)*(b-a)*0.5

Yes.

> --this slope function calculate the function f's "slope" at interval [a,b]
> slope f a b = (f b - f a)/(b-a)

Not needed: compare the results of integrating the whole interval [a,b] 
with the sum of the integrals of the half intervals [a,m] and [m,b].

> --if the slope of two interval is close within a tolerance e=0.001, we 
> return one of the integrate formular, of course it should
> --multiply by 2. If not, recursively call integrate function again.

This might work; I am not sure.

> integrate f a b =  if abs (slope f a (half a b) - slope f (half a b) b) <e
>    then (trape f a (half a b))*2
>    else integrate f a (half a b) + integrate f (half a b) b  where e =0.001
> --the result is like following which is quite close to your test:
>  
> A1> integrate sin 0 pi
> 2.0

If you can get answers as close as that, go for it.

Peter
So it is mentioned in class...
Hi,

Actually our prof. corrected this mistake in Q8 in the
class, together with 2 other mistakes in Q1 and Q2. 
You can get the corrected version of assignment from
his web.
I use a slightly different algorithm with yours: my
first approximation simply uses the trapeziodal rule;
second(better) approximation is to split the interval
into two equal parts, then apply trapeziodal rule to
both and then take their summation -- I don't mutiply
the result of one half by 2 and take it as result --
that's the difference from yours.  The rest of the
algorithm is same.  In case of e=0.001, I got the same
result also.

Cheers,
Linda   

The declaration of an object should not add parentheses after constructor

 
Hi Professor,
 
As I asked you in class the VC++ simply won't recognize the declaration of an object with parentheses added after constructor.
See following simple code:
 
#include <iostream>
 
using namespace std;
 
class MyClass
{
public:
 void test() { cout<<"This is a test!";}
};
 
int main()
{
 MyClass M();
 M.test(); //If M is an object, M should be able to invoke test()
     //function, but it won't pass compilation simply because
     //compiler recognize it as a function name.
 
 //However, if we use the following syntax, it works.
 MyClass* temp = new MyClass();
 temp->test();
 
 return 0;
}
 
 
This  won't pass compilation for statement M.test(); And compiler gives out an error:
error C2228: left of '.test' must have class/struct/union type
Error executing cl.exe.
 
It confirms my idea that compiler will treat M() as a sort of function name or whatever (making no senses here). But for the dynamic memory allocation, it works fine.
 
Just to inform you the result.
 
Thank you for your time.
 
Nick Huang/Qingzhe Huang
 
 

                                                         back.gif (341 bytes)       up.gif (335 bytes)         next.gif (337 bytes)

Hosted by www.Geocities.ws

1