Я думаю, что это должно сделать трюк. Я просто добавил if(isset
и добавил конкатенацию к переменным в теле, чтобы отделить PHP от HTML.
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = 'contact@yoursite.com';
$subject = 'Customer Inquiry';
$body = "From:" .$name."\r\n E-Mail:" .$email."\r\n Message:\r\n" .$message;
if (isset($_POST['submit']))
{
if (mail ($to, $subject, $body, $from))
{
echo '<p>Your message has been sent!</p>';
}
else
{
echo '<p>Something went wrong, go back and try again!</p>';
}
}
?>
Почему C ++ не использует .
, где он использует ::
, потому что именно так определяется язык. Одна из правдоподобных причин - ссылаться на глобальное пространство имен, используя синтаксис ::a
, как показано ниже:
int a = 10;
namespace M
{
int a = 20;
namespace N
{
int a = 30;
void f()
{
int x = a; //a refers to the name inside N, same as M::N::a
int y = M::a; //M::a refers to the name inside M
int z = ::a; //::a refers to the name in the global namespace
std::cout<< x <<","<< y <<","<< z <<std::endl; //30,20,10
}
}
}
Не знаю, как Java решает это. Я даже не знаю, есть ли в Java глобальное пространство имен. В C # вы ссылаетесь на глобальное имя, используя синтаксис global::a
, что означает, что даже C # имеет оператор ::
.
, но я не могу представить ни одной ситуации, в которой синтаксис
Кто сказал, что синтаксис, подобный
a.b::c
, не является законным?Рассмотрим эти классы:
struct A { void f() { std::cout << "A::f()" << std::endl; } }; struct B : A { void f(int) { std::cout << "B::f(int)" << std::endl; } };
Теперь см. Это ( ideone ):
B b; b.f(10); //ok b.f(); //error - as the function is hidden
b.f()
не может быть вызвано так, как функция скрыта, а GCC дает это сообщение об ошибке:error: no matching function for call to ‘B::f()’
Для вызова
b.f()
(или, скорее,A::f()
) вам нужен оператор разрешения области видимости:b.A::f(); //ok - explicitly selecting the hidden function using scope resolution
Почему у C ++ есть оператор :: вместо использования. оператор для этой цели?
Причина дана самим Страуступом:
В C с классами точка использовалась для выражения членства в классе как а также выражение выбора элемента определенного объекта.
Это было причиной некоторой незначительной путаницы, а также может использоваться для построения неоднозначных примеров. Чтобы облегчить это,
::
был введен для обозначения членства в классе, а.
был сохранен исключительно для принадлежности к объекту(Bjarne Stroustrup A История C ++: 1979-1991 стр. 21 - § 3.3.1)
Кроме того, это правда, что
они делают разные вещи, поэтому они могут выглядеть иначе
< / blockquote>действительно
В
N::m
ниN
, ниm
не являются выражениями со значениями;N
иm
- имена, известные компилятору, а::
выполняет разрешение области (времени компиляции), а не оценку выражения. Можно представить себе возможность перегрузки x :: y, где x - это объект, а не пространство имен или класс, но это, вопреки первым появлениям, включает введение нового синтаксиса (чтобы разрешитьexpr::expr
). Неясно, какие преимущества принесет такое усложнение.Оператор
.
(точка) в принципе может быть перегружен с использованием того же метода, что и для->
.(Bjarne Stroustrup's C ++ Стиль и техника FAQ )
В отличие от Java, C ++ имеет множественное наследование. Вот один из примеров, где важное значение имеет разрешение области видимости, о которой вы говорите:
#include <iostream>
using namespace std;
struct a
{
int x;
};
struct b
{
int x;
};
struct c : public a, public b
{
::a a;
::b b;
};
int main() {
c v;
v.a::x = 5;
v.a.x = 55;
v.b::x = 6;
v.b.x = 66;
cout << v.a::x << " " << v.b::x << endl;
cout << v.a.x << " " << v.b.x << endl;
return 0;
}
test.foo.blah = 10
? Или test.base.blah = 10
, где base
- ключевое слово?
– Nawaz
18 February 2012 в 06:13
test.foo.blah
неоднозначен; это элемент blah
или thingy
члена базового класса blah
? Java (как я понимаю) оборачивается этим, заявляя, что это всегда член; вы можете получить только переменные-члены базового класса, нажав тип.
– Nicol Bolas
18 February 2012 в 06:15
base
вы хотели использовать.
– Mankarse
18 February 2012 в 06:16
base.blah
намного проще (и менее неудобно).
– Nawaz
18 February 2012 в 06:21
base
в любом месте. Это вполне возможно. Ключевые слова не сложно из-за компилятора; это сложно, потому что это делает вещи, которые использовали i>, эти ключевые слова ломаются. Даже ключевое слово, зависящее от контекста, означает, что вы не можете иметь тип с именем base
.
– Nicol Bolas
18 February 2012 в 06:31
::
. См. Руководство Cfront E, стр. 22 (25 в pdf) - ::
, но никаких признаков множественного наследования в описании классов нет.
– Jules
3 April 2016 в 16:20
Чтобы ответить на окончательный бит вопроса о приоритете оператора:
class A {
public:
char A;
};
class B : public A {
public:
double A;
};
int main(int c, char** v)
{
B myB;
myB.A = 7.89;
myB.A::A = 'a';
// On the line above a hypothetical myB.A.A
// syntax would parse as (myB.A).A and since
// (myB.A) is of type double you get (double).A in the
// next step. Of course the '.' operator has no
// meaning for doubles so it causes a syntax error.
// For this reason a different operator that binds
// more strongly than '.' is needed.
return 0;
}
.
, прежде чем принимать решение о двусмысленности?
– Nicol Bolas
18 February 2012 в 06:23
.
для разрешения области (см. исходный код Cfront, который был написан для компиляции Cpre: softwarepreservation.org/projects/c_plus_plus/cfront/release_e/… ) , Выяснив, как это сделать, я сомневаюсь, что Страуструп тогда отказался бы от этого, когда он переопределит язык. Поэтому я не думаю, что техническая сложность его использования была частью причины.
– Jules
3 April 2016 в 16:23
Я всегда предполагал, что C ++ dot / :: использование было выбором стиля, чтобы сделать код более удобным для чтения. Как пишет OP, «они делают разные вещи, поэтому они должны выглядеть по-другому».
Начиная с C ++, давным-давно, до C #, я нашел использование пустых строк. Я привык видеть A::doStuff();
B.doStuff();
, и знать, что первая является регулярной функцией, в пространстве имен, а вторая является функцией-членом в экземпляре B.
C ++ - это, может быть, мой пятый язык, после Basic, Assembly, Pascal и Fortran, поэтому я не думаю, что это синдром первого языка, и теперь я больше программист на C #. Но, ИМХО, если вы использовали оба варианта, двойная двоеточие типа C ++ для пространств имен лучше читается. Я чувствую, что Java / C # выбрали точки для того, чтобы (успешно) облегчить фронт кривой обучения.
Оператор разрешения масштаба (: :) используется для определения функции вне класса или когда мы хотим использовать глобальную переменную, но также имеет локальную переменную с тем же именем.
b.A.f
вместоb.A::f
. ЕслиA
является typename вместо переменной или функции, то использование.
может легко означатьscope resolution
вместо обычного значения. – Nicol Bolas 18 February 2012 в 05:42a.b::c
неразумным, вызывает у меня путаницу. Принял этот ответ, потому что я думаю, что он так же хорош, как и другие, но также указывает на мою ошибку. – Karu 18 February 2012 в 06:57