2009-12-15 84 views
4

我刚刚完成了我的第二个OOP类,我的第一个和第二个类都是用C#教的,但对于我的其他编程类,我们将使用C++。具体来说,我们将使用Visual C++编译器。问题是,我们需要学习C++自己的基础知识,而不需要从我们的教授那里过渡。所以,我想知道你们中的任何一个人是否知道我可以去学习C++的一些很好的资源,来自C#背景?从C#转换到C++,很好的参考?

我问这个是因为我注意到C#和C++之间存在很多差异,例如声明main方法int并返回0,并且您的main方法并不总是包含在类中。另外,我注意到你的所有类都必须写在你的主要方法之前,我听说这是因为VC++遵循自上而下的原则吗?

无论如何,你知道一些很好的参考吗?

谢谢! (还有,在那里我可以比较我用C#编写的简单程序,看看它们在C++中的样子,比如我在下面写的那个)。

using System; 
using System.IO; 
using System.Text; // for stringbuilder 

class Driver 
{ 
const int ARRAY_SIZE = 10; 

static void Main() 
{ 
    PrintStudentHeader(); // displays my student information header 

    Console.WriteLine("FluffShuffle Electronics Payroll Calculator\n"); 
    Console.WriteLine("Please enter the path to the file, either relative to your current location, or the whole file path\n"); 

    int i = 0; 

    Console.Write("Please enter the path to the file: "); 
    string filePath = Console.ReadLine(); 

    StreamReader employeeDataReader = new StreamReader(filePath); 

    Employee[] employeeInfo = new Employee[ARRAY_SIZE]; 

    Employee worker; 

    while ((worker = Employee.ReadFromFile(employeeDataReader)) != null) 
    { 
     employeeInfo[i] = worker; 
     i++; 
    } 

    for (int j = 0; j < i; j++) 
    { 
     employeeInfo[j].Print(j); 
    } 

    Console.ReadLine(); 

}//End Main() 


class Employee 
{ 
const int TIME_AND_A_HALF_MARKER = 40; 
const double FEDERAL_INCOME_TAX_PERCENTAGE = .20; 
const double STATE_INCOME_TAX_PERCENTAGE = .075; 
const double TIME_AND_A_HALF_PREMIUM = 0.5; 

private int employeeNumber; 
private string employeeName; 
private string employeeStreetAddress; 
private double employeeHourlyWage; 
private int employeeHoursWorked; 
private double federalTaxDeduction; 
private double stateTaxDeduction; 
private double grossPay; 
private double netPay; 

// -------------- Constructors ---------------- 

public Employee() : this(0, "", "", 0.0, 0) { } 

public Employee(int a, string b, string c, double d, int e) 
{ 
    employeeNumber = a; 
    employeeName = b; 
    employeeStreetAddress = c; 
    employeeHourlyWage = d; 
    employeeHoursWorked = e; 
    grossPay = employeeHourlyWage * employeeHoursWorked; 

    if (employeeHoursWorked > TIME_AND_A_HALF_MARKER) 
     grossPay += (((employeeHoursWorked - TIME_AND_A_HALF_MARKER) * employeeHourlyWage) * TIME_AND_A_HALF_PREMIUM); 

    stateTaxDeduction = grossPay * STATE_INCOME_TAX_PERCENTAGE; 
    federalTaxDeduction = grossPay * FEDERAL_INCOME_TAX_PERCENTAGE; 
} 

// --------------- Setters ----------------- 

/// <summary> 
/// The SetEmployeeNumber method 
/// sets the employee number to the given integer param 
/// </summary> 
/// <param name="n">an integer</param> 
public void SetEmployeeNumber(int n) 
{ 
    employeeNumber = n; 
} 

/// <summary> 
/// The SetEmployeeName method 
/// sets the employee name to the given string param 
/// </summary> 
/// <param name="s">a string</param> 
public void SetEmployeeName(string s) 
{ 
    employeeName = s; 
} 

/// <summary> 
/// The SetEmployeeStreetAddress method 
/// sets the employee street address to the given param string 
/// </summary> 
/// <param name="s">a string</param> 
public void SetEmployeeStreetAddress(string s) 
{ 
    employeeStreetAddress = s; 
} 

/// <summary> 
/// The SetEmployeeHourlyWage method 
/// sets the employee hourly wage to the given double param 
/// </summary> 
/// <param name="d">a double value</param> 
public void SetEmployeeHourlyWage(double d) 
{ 
    employeeHourlyWage = d; 
} 

/// <summary> 
/// The SetEmployeeHoursWorked method 
/// sets the employee hours worked to a given int param 
/// </summary> 
/// <param name="n">an integer</param> 
public void SetEmployeeHoursWorked(int n) 
{ 
    employeeHoursWorked = n; 
} 

// -------------- Getters -------------- 

/// <summary> 
/// The GetEmployeeNumber method 
/// gets the employee number of the currnt employee object 
/// </summary> 
/// <returns>the int value, employeeNumber</returns> 
public int GetEmployeeNumber() 
{ 
    return employeeNumber; 
} 

/// <summary> 
/// The GetEmployeeName method 
/// gets the name of the current employee object 
/// </summary> 
/// <returns>the string, employeeName</returns> 
public string GetEmployeeName() 
{ 
    return employeeName; 
} 

/// <summary> 
/// The GetEmployeeStreetAddress method 
/// gets the street address of the current employee object 
/// </summary> 
/// <returns>employeeStreetAddress, a string</returns> 
public string GetEmployeeStreetAddress() 
{ 
    return employeeStreetAddress; 
} 

/// <summary> 
/// The GetEmployeeHourlyWage method 
/// gets the value of the hourly wage for the current employee object 
/// </summary> 
/// <returns>employeeHourlyWage, a double</returns> 
public double GetEmployeeHourlyWage() 
{ 
    return employeeHourlyWage; 
} 

/// <summary> 
/// The GetEmployeeHoursWorked method 
/// gets the hours worked for the week of the current employee object 
/// </summary> 
/// <returns>employeeHoursWorked, as an int</returns> 
public int GetEmployeeHoursWorked() 
{ 
    return employeeHoursWorked; 
} 

// End --- Getter/Setter methods 

/// <summary> 
/// The CalcSalary method 
/// calculates the net pay of the current employee object 
/// </summary> 
/// <returns>netPay, a double</returns> 
private double CalcSalary() 
{ 
    netPay = grossPay - stateTaxDeduction - federalTaxDeduction; 

    return netPay; 
} 

/// <summary> 
/// The ReadFromFile method 
/// reads in the data from a file using a given a streamreader object 
/// </summary> 
/// <param name="r">a streamreader object</param> 
/// <returns>an Employee object</returns> 
public static Employee ReadFromFile(StreamReader r) 
{ 
    string line = r.ReadLine(); 

    if (line == null) 
     return null; 

    int empNumber = int.Parse(line); 
    string empName = r.ReadLine(); 
    string empAddress = r.ReadLine(); 
    string[] splitWageHour = r.ReadLine().Split(); 
    double empWage = double.Parse(splitWageHour[0]); 
    int empHours = int.Parse(splitWageHour[1]); 

    return new Employee(empNumber, empName, empAddress, empWage, empHours); 
} 

/// <summary> 
/// The Print method 
/// prints out all of the information for the current employee object, uses string formatting 
/// </summary> 
/// <param name="checkNum">The number of the FluffShuffle check</param> 
public void Print(int checkNum) 
{ 
    string formatStr = "| {0,-45}|"; 

    Console.WriteLine("\n\n+----------------------------------------------+"); 
    Console.WriteLine(formatStr, "FluffShuffle Electronics"); 
    Console.WriteLine(formatStr, string.Format("Check Number: 231{0}", checkNum)); 
    Console.WriteLine(formatStr, string.Format("Pay To The Order Of: {0}", employeeName)); 
    Console.WriteLine(formatStr, employeeStreetAddress); 
    Console.WriteLine(formatStr, string.Format("In The Amount of {0:c2}", CalcSalary())); 
    Console.WriteLine("+----------------------------------------------+"); 
    Console.Write(this.ToString()); 
    Console.WriteLine("+----------------------------------------------+"); 
} 

/// <summary> 
/// The ToString method 
/// is an override of the ToString method, it builds a string 
/// using string formatting, and returns the built string. It particularly builds a string containing 
/// all of the info for the pay stub of a sample employee check 
/// </summary> 
/// <returns>A string</returns> 
public override string ToString() 
{ 
    StringBuilder printer = new StringBuilder(); 

    string formatStr = "| {0,-45}|\n"; 

    printer.AppendFormat(formatStr,string.Format("Employee Number: {0}", employeeNumber)); 
    printer.AppendFormat(formatStr,string.Format("Address: {0}", employeeStreetAddress)); 
    printer.AppendFormat(formatStr,string.Format("Hours Worked: {0}", employeeHoursWorked)); 
    printer.AppendFormat(formatStr,string.Format("Gross Pay: {0:c2}", grossPay)); 
    printer.AppendFormat(formatStr,string.Format("Federal Tax Deduction: {0:c2}", federalTaxDeduction)); 
    printer.AppendFormat(formatStr,string.Format("State Tax Deduction: {0:c2}", stateTaxDeduction)); 
    printer.AppendFormat(formatStr,string.Format("Net Pay: {0:c2}", CalcSalary())); 

    return printer.ToString(); 

} 
} 

回答

7

C++和C#是不同的语言,具有不同的语义和规则。没有一种方法可以从一种切换到另一种。你将不得不学习C++。

对此,resources to learn C++问题中的一些可能会为您提供有趣的建议。例如,还可以搜索C++ books - 请参阅definitive C++ book guide and list

无论如何,您将需要大量的时间来学习C++。 如果你的老师希望你全身心地了解C++,你的学校有一个严重的问题。

+1

+1张贴我要去的! :-) – 2009-12-15 01:17:20

+0

好的,谢谢你的好建议。 – Alex 2009-12-15 01:39:19

+1

我怀疑他们希望他突然知道它。第一对夫妇的任务通常很简单,你可以随心所欲地选择语言。 – mpen 2009-12-15 06:00:01

6

我的建议是这样的:

不要在C#方面认为C++的。从头开始,并尝试从一本好的,坚实的C++教科书中学习C++。

试图将C++映射到C#思维方式不会让你成为一个优秀的C++开发人员 - 它确实非常不同。从C#移植到C++(不是C++/CLI,而是C++)非常困难,因为如此多的C#实际上是.NET框架,在C++中工作时将不可用。

此外,在C++中完成的工作与C#中的工作方式有很多不同之处。就像C#泛型看起来像C++模板一样,它们是非常不同的,而且这种变化在C++中变得非常普遍。

你的经验会使许多事情变得更容易,但最好把它想象成它是一个完全不同的语言。

1

这里没有一个真正的比较“地方”,我知道检查你的代码与它的C++实现。我推荐的是,你找到一个OO开发的本地专家,并让他/她对你的示例代码进行彻底的代码审查。之后,他或她可能会和你一起去C++端口,你会发现这些语言并没有太大的不同。 (图书馆是你可以找到有意义差异的地方,而不是语言;但在这一点上这可能与你无关)。

代码审查不同于要求你的教授或助教为您的评分工作。这位教授很可能没有时间和你一起做全面的评估(尽管他或她可能会在办公室里超过几分。)一位优秀的代码审查人员将逐行引导您的代码,提供反馈和问题,例如“为什么您认为我会或不会这样做?”,或者“您是否考虑过如果您的需求更改为X?“,或者”如果其他人想要重用Y,这个代码会发生什么?“在审查过程中,他们将帮助强化良好的面向对象原则。你会从很多人身上学到很多新东西。 (找到一个好人可能是一件困难的事情 - 如果可能的话得到一个推荐人,或者寻求一个熟悉重构的人,也许请求助理教授或研究生做一个。)使用上面的代码,我期望这将需要一个或两个小时。

你也可以考虑让居民们的StackOverflow通过电子邮件或直接在评论/答案做代码审查和你在一起。我相信你会得到丰富多彩的答案,并且讨论可能是教育性的。

这也是宝贵的做一个有经验的人的代码,代码审查 - 询问有关问题:“你为什么这样做?”可以导致洞察力;当新手在guru的代码中发现错误时,总是非常有趣。

你已经通过审查走后与专家,看看他们是什么样的(甚至只是一个或2条评论)可考虑做代码审查与同龄人的教室,在那里你每次审查对方的代码。即使是没有经验的眼睛也可能会提出一个触发更深层理解的问题。

我知道你有C++课堂作业来考虑,但你也需要有面向对象设计的基本原理的更多实践。一旦你有了更多的实践经验,你会发现所有基于C的语言几乎都只是一组常见语法的语法变体 - 尽管某些语言特性会使你的工作更轻松,有些语言会使它更难。

1

许多高校在C++/C++之前甚至是C++都教C#/ Java。他们这样做是因为有人相信,你将会用一种语言更加正确地学习面向对象的开发,这种语言不允许你使用在C++中仍然可能的非OO方法。

你应该问问你的教授,如果是这样的话。

如果是这样,你应该会发现他/她会轻轻地引入C++细节,并且只在必要的地方。目的是让您能够将您在C#中学到的许多良好实践应用到您的C++代码中。你还可以更清楚地看到C++允许你打破一些面向对象的规则,甚至更重要的是甚至可以有用。

另外,如果你发现你的教授跃起直入C++的指针和内存管理没有一些指导,然后(如别人说的)过程看起来不是很精心策划的。在这种情况下,您可能需要考虑获取Stroustrup的C++ Programming Language的副本。

-1

要始终牢记的一件事是,在C#中传递对象时,实际上是将对该对象的引用传递给它。

C#:void EnrollStudent(Student s) s是实际对象的引用(在内存中的位置)。

C++:void EnrollStudent(Student s) s是实际的对象。与对象一样大,这就是你将在堆栈中占用多少空间。

的C++等价的C#方法是 void EnrollStudent(Student* s)

+1

我以为C++的等价物是无效的EnrollStudent(Student&s)。没有区别吗? – Alex 2010-01-07 15:26:04

+0

@Alex您指定的函数原型将通过引用传递Student对象。在C++中这样做将允许参数被函数修改(如在C#中),但是您仍然将整个对象传递给函数,而不是传递指针的'void EnrollStudent(Student * s)'。同样的结果,但更好的表现。 看看这个链接:http://pages.cs.wisc.edu/~hasti/cs368/CppTutorial/NOTES/PARAMS.html – 2010-01-08 18:40:37

+0

在引用和指针之间的性能真的有区别吗?我认为引用在编译时被翻译成指针。 – gtrak 2011-01-13 20:37:05