4

我刚刚完成了我的第二节 OOP 课程,我的第一节和第二节课都是用 C# 教授的,但是对于我其余的编程课程,我们将使用 C++。具体来说,我们将使用可视化 C++ 编译器。问题是,我们需要自己学习 C++ 的基础知识,而不是从我们的教授那里过渡。所以,我想知道你们中是否有人知道一些好的资源,我可以去学习 C++,来自 ac# 背景?

我问这个是因为我注意到 C# 和 C++ 之间的许多差异,例如声明你的main方法 int,并返回一个 0,并且你的 main 方法并不总是包含在一个类中。另外,我注意到你所有的类都必须在你的 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();

}
}
4

6 回答 6

7

C++ 和 C# 是不同的语言,具有不同的语义和规则。从一种切换到另一种没有硬性和快速的方法。你必须学习 C++。

为此,一些学习 C++问题的资源可能会给你一些有趣的建议。还可以搜索C++ 书籍- 例如,请参阅权威的 C++ 书籍指南和列表

无论如何,您都需要大量时间来学习 C++。如果您的老师希望您突然了解 C++,那么您的学校有一个严重的问题。

于 2009-12-15T01:15:58.307 回答
7

我的建议是这样的:

不要从 C# 的角度来考虑 C++。从头开始,并尝试从一本好的、扎实的 C++ 教科书中学习 C++。

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

此外,在 C++ 中做的很多事情都与在 C# 中做的不同。尽管 C# 泛型看起来像 C++ 模板,但它们非常不同,并且在 C++ 中工作时,这种变化确实变得普遍。

您的经验将使许多事情变得更容易,但最好将其视为它的本来面目——一种完全不同的语言。

于 2009-12-15T01:17:28.617 回答
1

我知道没有真正的比较“地方”来检查你的代码与它的 C++ 实现。相反,我建议您找一位本地 OO 开发专家,让他或她对您的示例代码进行彻底的代码审查。在那之后,他或她可能会和你一起移植到 C++,你会发现这些语言并没有太大的不同。(图书馆是您可以找到有意义差异的地方,而不是语言;但此时这可能与您无关。)

代码审查不同于要求你的教授或助教给你的工作评分。教授可能没有时间与您进行全面审查(尽管他或她可能会在他们的办公室中复习一些要点。)一位优秀的代码审查员会逐行引导您完成代码,并提供反馈以及诸如“你为什么认为我会或不会这样做?”或“你是否考虑过如果你的需求更改为 X 会发生什么?”或“如果其他人想要重用此代码会发生什么情况”等问题是吗?” 在您进行审查时,他们将帮助加强良好的 OO 原则。你会从做过很多这样的人那里学到很多新东西。(找到一个好人可能是一项艰巨的任务——如果可能的话,请推荐一个人,或者找一个熟悉重构的人。

您还可以考虑通过电子邮件或在评论/答案中要求 StackOverflow 居民与您一起进行代码审查。我相信你会得到丰富多彩的答案,而且讨论可能会很有教育意义。

对有经验的人的代码进行代码审查也很有价值——询问“你为什么这样做?”的问题。可以带来洞察力;当新手在大师的代码中发现错误时,总是很有趣。

在您与专家进行审查以了解他们的情况(即使只是一两次审查)后,请考虑与您的课堂同伴一起进行代码审查,在那里你们每个人都审查对方的代码。即使是没有经验的眼睛也可能会提出一个引发更深入理解的问题。

我意识到您需要考虑 C++ 课业,但您还需要更多练习 OO 设计的基础知识。一旦你有更多的实践经验,你会发现所有基于 C 的语言几乎都只是一组通用思想的语法变体——尽管一些语言特性会使你的工作更容易,但有些会使工作变得更难。

于 2009-12-15T05:57:07.017 回答
1

许多学院和大学在 C#/Java 之前甚至代替 C++ 来教授 C#/Java。他们这样做是因为相信您将使用一种不允许您使用在 C++ 中仍然可以使用的非 OO 方法的语言更正确地学习面向对象的开发。

你应该问问你的教授是不是这样。

如果是,您应该会发现他/她只会在必要时温和地介绍 C++ 细节。目的是您将能够将您在 C# 中学到的许多良好实践应用到您的 C++ 代码中。您还将更清楚地看到 C++ 允许您在哪些地方打破一些 OO 规则,更重要的是,这甚至可以在哪些地方有用。

或者,如果您发现您的教授在没有一些指导的情况下直接跳入 C++ 指针和内存管理,那么(正如其他人所说)该课程看起来没有很好的计划。在这种情况下,您可能需要考虑获得一份Stroustrup的C++ 编程语言的副本。

于 2009-12-15T06:41:26.840 回答
0

针对您的具体情况的一本书:面向 C# 开发人员的 Pro Visual C++ 2005

替代文字

MSDN 还指出了它们之间的一些差异。)

于 2010-01-07T02:49:55.540 回答
-1

要始终牢记的一件主要事情是,在 C# 中,当您传递一个对象时,实际上是在传递对该对象的引用。

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

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

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

于 2010-01-07T02:43:24.180 回答